Output first line of temporary file - bash

I am writing a script to checkout the latest git commit with the word "merge" inside the commit message. I am trying to output the latest git commit line to see if my script is working so far
tempfile=$((mktemp))
tempfile2=$((mktemp))
git log --oneline >> $tempfile
grep -i "merge" $tempfile | head -1 > $tempfile2
cat $tempfile2
I was expecting the script to output just one line containing "merge" however it outputs the whole log. I actually just want to take the commit id and git checkout the latest "merge" file to a detached head state. If anyone could help me with what to do next I would greatly appreciate it. Thank you

Related

Git Extract modification in one string line

Any good combination of Bash + git diff to get in one line the only change that I made in my file?
I'm using form Jenkins DSL, and the best that I get so far is this
"${sh(script: "git diff --shortstat", returnStdout: true)}".trim() == "1 file changed, 1 insertion(+), 1 deletion(-)"
But what I would love to have is the "hello world" text that I just add into one of the files.
If you've got just one hunk,
git diff -U0 | sed 1,/^##/d
and strip the leading character off.

GIT: How to search through older versions of a file and list all versions that match the search criteria?

I have a repo that contains a certain file. I need to create a git script that searches through all the previous versions of this file and lists the commit SHAs that contain a specific string.
I want to have a list of all the commits that in their version that string exists.
The best answer I could find is here (but not good enough): https://stackoverflow.com/a/4705617/4441211
This solution is not good enough because this only finds where there was a change (i.e the search term was added or removed). Does anybody have a better idea how to do this?
To look for a pattern <pattern> in a file <path/to/file> within a commit <commit> : use git grep
git grep -e <pattern> <commit> -- <path/to/file>
Check git help grep for more details : many options are copied of the original grep command (-l to only list file names, -q to drop output ...)
If your intention is to scan all commits looking for a string (not just the commits where a change occured) :
git rev-list HEAD will give you the list of all commits in the ancestry of your active branch,
write a loop to repeatedly call git grep on these commits.
For example :
git rev-list HEAD | while read sha; do
git grep -q -e <pattern> $sha -- <path/to/file> && echo $sha
done

Get first line by git log with a single command on windows

Seems to be pretty simple question that drives me crazy already. Trying get the first line from the commit list that I've got by following command:
E:\Repos\reports>git log --oneline --reverse
origin/master..feature/a123
Getting following output
d8c38ac Dummy change to invoke deploy
aaca9eb (HEAD -> feature/a123, origin/feature/a123) Add transation isolation
Then trying to do
E:\Repos\reports>git log --oneline --reverse
origin/master..feature/a123 -n 1
and doesn't matter do I use --reverse or not, I'm always getting aaca9eb commit
Yeah, that's frustrating because the limiting of commits by number (-n) happens before the --reverse.
Though you can pipe it to a tail :
git log --oneline --reverse origin/master..feature/a123 | tail -1

git pull always fails, but git fetch/merge are fine

When I git pull in any repository, I always get the following merge error:
aetherboard:shwangster shwangster$ git pull -v
From github.com:sirspinach/shwangster
= [up to date] master -> origin/master
merge: 012012012012012012012012012012012012012012012012012012012012 - not
something we can merge
On the other hand, git fetch and git merge origin/master work like a charm. So I've been able to work around this problem for a while. However, I needed to update brew today, and the same error prevents me from doing that.
Here is the output from brew update, which shows git again attempting to merge with the mysterious 0120120120120....
aetherboard:gitrepos shwangster$ brew update
merge: 012012012012012012012012012012012012012012012012012012012012 - not
something we can merge
Error: Failure while executing: git pull -q origin refs/heads/master:refs/remotes/origin/master
There's a clue in the other (pretty much exact duplicate) question that Kaz noted in a comment, that the problem went away when pyenv was taken out of $PATH.
Here's the bit from the pull script that takes the FETCH_HEAD trace and turns it into an argument to git merge (or to git rebase when doing a rebasing pull):
merge_head=$(sed -e '/ not-for-merge /d' \
-e 's/ .*//' "$GIT_DIR"/FETCH_HEAD | \
tr '\012' ' ')
(By the way, note that those are tabs before and after not-for-merge and in the second -e argument to sed. Cut-and-paste generally turns tabs into spaces, and did here.)
I imagine the sed part is working correctly and the failure occurs with the tr invocation. In fact, it looks like whatever tr is being used, is simply spitting out the 012 string (for a total of 60 characters, or 20 instances of the three-character group—not sure how that happens given that the sed output is, or should be, a 40-character SHA-1).
If your shell is sh or bash, see what:
$ type tr
prints. If you use a csh variant, which tr will show you what it will run. (I'm not sure off-hand what to use for dash and zsh.) If you get something other than /usr/bin/tr, that may explain the problem. (If you do get /usr/bin/tr see what type sed or which sed says: these should be /usr/bin/sed.)

Yanking text from the previous stdout onto the command line

I'd like to set up my Bash in such a way that I could yank text from the previous command's stdout. The example use case I'll use is resolving conflicts during a git rebase.
$ git status
# Not currently on any branch.
# Unmerged paths:
# (use "git reset HEAD <file>..." to unstage)
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
# both modified: app/views/report/index.html.erb
#
$ vim app/views/report/index.html.erb
# .... edit, resolve conflicts ....
$ git add <Alt+.>
The problem is that the easiest way to grab the filename for the 2nd command (vim ...) is to move my hand over to the mouse. One option is screen, but that has its own set of issues as a day-to-day shell. (Not the least of which is that I use and abuse Ctrl+A as a readline shortcut)
Where could I start at making this work for me? Ideally I'd like to be able to pull the Nth line from the stdout of the previous command somewhere that I can manipulate it as a command.
Other than using the mouse, the only way I can think of is to use grep, sed and/or awk, perhaps with tee and/or a Bash function and process substitution and/or process and/or command substitution:
vim $(git status | tee /dev/tty | grep ...)
or
var=$(git status | tee /dev/tty | grep ...)
vim "$var"
git add "$var"
The tee allows you to see the full output while capturing the modified output. Creating a function would allow you to easily pass an argument that would select a certain line:
var=$(some_func 14)
etc.
The disadvantage is that you have to do this from the start. I don't know of any way to do this after the fact without using screen or some other output logging and scripting a rummage through the log.
I don't know of a good, clean solution, but as a hack you could try the script command, which logs all input and output to a file. For GNU script:
$ script -f
Script started, file is typescript
$ ls -1
bar
baz
foo
typescript
$ echo $(tail -3 typescript | head -1)
foo
pipe the output through sed:
git status | sed -n '5p'
to get the 5th line

Resources