On Sunday, 6 January 2013 at 19:50:47 UTC, Andrei Alexandrescu wrote:
Sent this to dmd-internals, opening for a broader discussion:

Hello,


I wonder how we can define a few aliases of project-wide usefulness to git. For example, I tried today to get the latest and greatest phobos into my repo, and got a bunch of conflicts. I searched a while on the net to figure what the command for "just get the latest remote into my local copy", which is entirely possible but not obvious and not easy to find. I got it from here: http://goo.gl/pWvVB and the invocation is:

git pull --rebase -s recursive -X ours

Question: Do you know what exactly does this command do?

Git is a very powerful and flexible system. Unfortunately, it is also comparatively more complicated than its competitors, svn and hg. Incorrect usage, especially by project maintainers, can result in history rewrites, duplicate commits, and lost changes. This has already happened multiple times in the past.

Earlier I noticed some discussion regarding how Walter attempted to follow a guide on the wiki regarding the release process. The problem is that (from what I gathered) he attempted to simply run the commands listed there, without understanding each one's exact effect and purpose. An observation was raised that the guide was incomplete - however, I believe the iteration at that point was written as a guideline (a general outline of what needs to be done) as opposed to strict step-by-step instructions. When stumped with a merge, he elected to use the "git cherry-pick" command to copy the commits on top of his HEAD - however, this duplicates the commits' contents and results in duplicate commits in the repository.

I think you're trying to solve the wrong problem...

Back to your question. Let's look at the command you posted:

git pull --rebase -s recursive -X ours

From my understanding, this this is what will happen:

1. Fetch whatever commit objects that are absent from your tree but are present in the remote branch, and copy them to your tree. So far so good.
2. Rewind your HEAD to the tip of the branch you just pulled.
3. Take each commit that are in your branch's history, but are not in the remote's history, and re-apply them on top of the new HEAD. This creates new commit objects, with new SHA-1 hashes. Anything that builds upon the old SHA-1 hashes (e.g. if you've already uploaded these commits anywhere) will break. (--rebase rewrites history!) 4. Whenever there is a merge conflict, it will THROW AWAY your change and automatically apply the other change.

Was this your intention?

Now, the question you should ask: WHY did you get a merge conflict?

Was it a case of you and someone else actually changing the same bit of code? Or was it another instance of git abuse and someone force-pushing after someone else already pulled the code?

If the merge conflict is genuine, and you don't want to deal with the merge, you should abort the merge, save your work as a new branch, and reset the current branch to the remote's:

$ git merge --abort
$ git branch branch-name-for-my-work
$ git reset --hard origin/master

(substitute "origin" for the remote name, and "master" for the remote branch name).

If you want to throw away any commits that are in your local branch but not in the remote branch, just run the third command.

-- Vladimir, and too much coffee

Reply via email to