Why git cherry-pick leaves uncommitted changes exits with non-zero - git-cherry-pick

Very often, my git appears like this:
A <- B <- C <- D <- E <- HEAD
It happens that I need to create a new branch based on B and only the changes in D. Here are the commands I do:
git checkout B -q -f -b release
git cherry-pick D
The cherry pick commands exits with code 53 and leaves all the changes in D uncommitted in branch release.
More info: this is under Windows. The commands above are part of my release process which I run under PowerShell. When I do the same procedure in Git Bash, cherry pick works just fine. Is this (yet another) EOL issue? I tried adding -Xignore-all-space but error remains.
Context: as part of my release process, I pick a cut-off commit (e.g. B), modify version files to include build time, release author, etc. Just before I can commit my versioning changes, someone else introduces commit C. When I commit my versioning changes, it becomes D. My release process above is to ensure that binaries are compiled with A <- B <- D. How can I make that happen smoothly?

Problem was my PATH var. I had it set like:
set PATH=%PATH%;"C:\Program Files (x86)\Git\mingw32\bin"
I changed to:
set PATH=%PATH%;C:\Program Files (x86)\Git\mingw32\bin
And problem was solved.

Related

How to fix merge conflicts for a lot of files in git?

I am using the git mergetool command to fix conflicts. However I have thousands of conflicts, is there way to simplify this so I get everything from the remote?
I am asked to enter c, d or a in the command.
{local}: deleted
{remote}: created file
Use (c)reated or (d)eleted file, or (a)bort?
Since I have thousands of files, I don't want to keep sending c. Is there way to just do this in bulk?
You can solve this outside of git mergetool: run git status --porcelain to get a list of all unmerged files and their states in machine-readable format.
If your Git is new enough, it will support --porcelain=v2. See the git status documentation for details on the output formats. Output format v2 is generally superior for all purposes, but you should be able to make do with either one.
Next, you must write a program. Unfortunately Git has no supplied programs for this. Your program can be fairly simple depending on the specific cases you want to solve, and you can use shell scripting (sh or bash) as the programming language, to keep it easy.
Since you're concerned about the cases where git mergetool says:
Use (m)odified or (d)eleted file, or (a)bort?
you are interested in those cases where the file name is missing in the stage 1 ("base") version and also missing in the stage 2 ("local") version, but exists in the stage 3 ("remote") version. (See the git status documentation again and look at examples of your git status --porcelain=v2 output to see how to detect these cases. Two of the three modes will be zero.) For those particular path names, simply run git add on the path name to mark the file as resolved in favor of the created file.
Once you have marked all such files, you can go back to running git mergetool to resolve additional conflicts, if there are any.
Note that your "program" can consist of running:
git status --porcelain=v2 > /tmp/commands.sh
and then editing /tmp/commands.sh to delete all but the lines containing files that you want to git add. Then change all of those lines to read git add <filename> where <filename> is the name of the file. Exit the editor and run sh /tmp/commands.sh to execute all the git add commands. That's your program!
supposing you want their change and modified yours you can do a pull as like:
git pull -X theirs
Other stackOverflow answers
git pull -X
git merge strategies this link will help understand any other merge strategies for the futuro
If you want that all the change you did will be deleted and you will be sync with the remote.
You should do the following:
git stash
git pull
And if you want to restore the change you did you should type:
git stash pop
Basically 'git stash' is moving the change to a temp repository.
you can learn more in:
NDP software:: Git Cheatsheet

Closing a mercurial branch creates a new head?

I'm trying to close an old branch that is no longer used but every time I do the close command on this branch it says a new head is created. Other branches do not have this issue. Does anyone know what my issue could be?
jchan#jchan-Z170N:~/eclipse-workspace/filtec-src/src$ hg --version
Mercurial Distributed SCM (version 3.7.3)
...
jchan#jchan-Z170N:~/eclipse-workspace/filtec-src/src$ hg update -r version1.5.11 -C
1367 files updated, 0 files merged, 6050 files removed, 0 files unresolved
jchan#jchan-Z170N:~/eclipse-workspace/filtec-src/src$ hg commit --close-branch -m "closing legacy branch"
created new head
when i query the list of branches again this branch keeps showing up:
hg branches
...
version1.5.11
Why is this? I am using mercurial command line on Ubuntu 16.04.
Found that I was able to use the tortoise Hg tool "thg" to search and find all the head commits on the miss behaving branch and then merge them all together. After merging all these similar heads together I was able to close the final head and now this branch no longer comes up in the hg branches query.

optional githook behaving as non-optional

I am attempting to make use of this gist in my workflow as post-merge and post-checkout git hooks.
#!/usr/bin/env bash
# MIT © Sindre Sorhus - sindresorhus.com
# git hook to run a command after `git pull` if a specified file was changed
# Run `chmod +x post-merge` to make it executable then put it into `.git/hooks/`.
changed_files="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"
check_run() {
echo "$changed_files" | grep --quiet "$1" && eval "$2"
}
# Example usage
# In this example it's used to run `npm install` if package.json changed
check_run package.json "npm install"
This claims to only run npm install if the package.json file is changed.
However on all the machines I have tried this on. The npm install command runs regardless of whether package.json has been changed or not.
To test this I have been creating a new branch at my current commit and then checking it out, thus triggering the post-checkout git hook. I would not expect npm install to run because the package.json is unchanged.
Visual Proof (note the npm warning text):
ORIG_HEAD should be replaced with HEAD#{1} as noted in this question ORIG_HEAD is an older, less reliable way to supposedly get the previous state of HEAD. In my case it was not being set.
TL;DR
Use a different post-checkout hook, that uses $1 instead of ORIG_HEAD. (Or, check the number of arguments to decide whether you are being invoked as the post-checkout or post-merge hook, to get the same effect. Or, if you know that reflogs are always enabled, use HEAD#{1} to get the previous value of HEAD.)
Discussion
Using ORIG_HEAD in a post-merge hook makes sense, because git merge sets ORIG_HEAD to the commit that was current before the merge. (If the merge was a true merge, rather than a fast-forward, the commit identified by MERGE_HEAD and the commit identified by HEAD^1 are necessarily identical. If the merge was a fast-forward, however, only MERGE_HEAD and the reflog will be able to locate the previous commit hash that was stored in HEAD before the merge.)
Using ORIG_HEAD in a post-checkout hook, however, is blatantly wrong, because git checkout does not set ORIG_HEAD. This means that if ORIG_HEAD even exists at all, it effectively points to some random commit. (Of course, it actually resolves to whatever commit was left in it by whatever command last updated it: git merge, git rebase, or any other command that writes to ORIG_HEAD. But the point here is that it does not have any relationship to the commit that was current before the checkout.) A post-checkout hook:
is given three parameters: the ref of the
previous HEAD, the ref of the new HEAD (which may or may not have
changed), and a flag indicating whether the checkout was a branch
checkout (changing branches, flag=1) or a file checkout (retrieving a
file from the index, flag=0). This hook cannot affect the outcome of
git checkout.
(That last sentence is not quite right. Although the post-checkout hook cannot stop checkout from having updated the index and work-tree, it can overwrite various work-tree or index contents, and if it produces a failure exit status, it causes git checkout itself to also produce a failure exit status.)
What this all means is that you need to take a different action in a post-checkout hook: use $1, the first parameter, to get the hash ID of the previous HEAD. Note that in exotic cases,1 the post-checkout hook is run on the initial git clone, so $1 can be the null-ref. (I'm now curious as to what it is when you use git checkout --orphan and then don't create the new branch, as well. It seems likely that $1 will be the null-ref here too.)
1The only way to get a post-checkout hook to run on git clone is to have git clone install the post-checkout hook. This is normally impossible, but can be done by pointing your Git to your own template directories that have actual hooks instead of just sample hooks.
Torek mentions:
This hook cannot affect the outcome of git checkout.
That last sentence is not quite right.
Although the post-checkout hook cannot stop checkout from having updated the index and work-tree, it can overwrite various work-tree or index contents, and if it produces a failure exit status, it causes git checkout itself to also produce a failure exit status.
That is now (Q4 2020, 3 years later) officially documented with With Git 2.29:
See commit 3100fd5 (27 Aug 2020) by Junio C Hamano (gitster).
(Merged by Junio C Hamano -- gitster -- in commit 2f1757e, 03 Sep 2020)
doc: clarify how exit status of post-checkout hook is used
Because the hook runs after the main checkout operation finishes, it cannot affect what branch will be the current branch, what paths are updated in the working tree, etc., which was described as "cannot affect the outcome of 'checkout'".
However, the exit status of the hook is used as the exit status of the 'checkout' command and is observable by anybody who spawned the 'checkout', which was missing from the documentation.
Fix this.
githooks now includes in its man page:
This hook cannot affect the outcome of git switch or git checkout,
other than that the hook's exit status becomes the exit status of these two commands.

How to manage git merge with essentially two masters?

we have the following situation:
At time point t0, we took snapshot of C++ project in Unix, which was not finished (release 1702 under Unix), and worked on it migrating to Linux. This was established as Master in a new GIT server.
At time point t1, I created a new branch from Master called 1702, and overwrote everything with the up to date Unix code.
During t1, I made another branch linux_not_working, which is a clone of Master branch.
Now, I tried to merge 1702 into linux_not_working, with git mergetool for handling conflicts, and the result is bad: for example I modified all of the project's Makefiles to work in Linux, and the merge did not even display conflicts, just replaced them with the old Unix ones from 1702 branch, also I did not find how to tell vimdiff to take ALL from REMOTE and not LOCAL (as I understand it, BASE has no meaning in this particular merge).
How best to perform this merge, when in a sense, I have two Masters going? I need to take any new additions from 1702, while KEEPING my customizations in linux_not working (manually, but its a lot of files so cherry pick is not ideal).
Any suggestions for the future? They are going to have to do it at least once more, while a contractor is working on 1703 release, and only later production development will shift to Linux.
Essentially, what I want to do is for GIT to tell me for each file: "File R and L are different, which one you want to keep? (allowing me to take different parts of each, IF it happened to have been modified by both branches)"
Thanks!
Essentially, what I want to do is for GIT to tell me for each file: "File R and L are different, which one you want to keep? (allowing me to take different parts of each, IF it happened to have been modified by both branches)"
If you don't need 3-way merge, you can simply check out the content of the branch and review the change with git gui.
$ git checkout -b manual-merge linux_not_working
$ git checkout 1702 . # overwrites source with 1702's one
$ git gui # take or leave each diff
$ git commi
(Or you may want to do it backwards.)
$ git checkout -b manual-merge-2 1702
$ git checkout linux_not_working .
$ git gui
$ git commit
Once you have manually-merged result, you can overwrite and commit as a merge.
$ git checkout 1702
$ git merge linux_not_working
$ git reset
$ git checkout manual-merge . # or manual-merge-2
$ git commit

Why isn't " $ git log --graph " working

I've recently tried using branches in git but while they work allright whatever I do I can't display the graph of my branches and merges. I've tried Giggle for ubuntu and gitk -all but none of them works as shown in this nettuts+ tutorial http://net.tutsplus.com/tutorials/other/easy-version-control-with-git/
I type in that
$ git log --graph #Sorry my sreenshot is missing h at the end
but instead of this...
...I get this...
I would be really pleased with a quick reply...
Here is what ' $ gitk --all ' outputs
You might be looking for git log --graph --all, likewise with gitk, I have an alias in my shell:
alias gk='gitk --all'
for just that purpose.
From git help log
--all
Pretend as if all the refs in refs/ are listed on the command line as <commit>.
So if you have branches a, b, and c, it's as if you told git to show the logs and graphs in this manner:
git log --graph a b c
Essentially, git log allows you to list any objets you can reference in what you want to see the logs for. You can even use it on a file, or multiple files files....
$ git log --oneline python-taboot.spec
c96d546 Straighten out the Makefile. Hey -- make rpm works now! Update a lot of docs. Fixes #34 - Taboot 'edit' mode should hint at the file type and give instructi
ea0d60b Version bumpskies to 0.4.0-1beta
a95cfbf Automatic commit of package [python-taboot] release [0.3.2-1].
d9e3ca6 Make python-argparse a Requires for el6 as well
ea7ed54 Automatic commit of package [python-taboot] release [0.3.1-1].
69eaea9 Add conditional Requires on python-argparse. Update README and release notes.
...
And so on...

Resources