On 1/6/13 4:03 PM, Vladimir Panteleev wrote:
On Sunday, 6 January 2013 at 19:50:47 UTC, Andrei Alexandrescu wrote:
git pull --rebase -s recursive -X ours
Question: Do you know what exactly does this command do?
I do now after having read about it at the end of several google searches.
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.
I agree it is important to be fluent with git. I'm an okay user but
currently unfit for an admin. Probably Walter is at a similar stage. I'm
doing my best to improve my knowledge in the limited time I have, and
part of it is discussing git here. So I hope you'll understand why I
find it contradictory to be reprimanded for doing so with the reproach
that I should be doing exactly what I'm doing.
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 agree we need to develop a better understanding of git. At the same
time it would be great to learn the meaning of commands from a guide
that actually works, as opposed to a sketch that doesn't quite.
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?
Yes, that was exactly my 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?
I have no idea. To the best of my understanding I had no meaningful work
in master proper. The one conflict I looked at was in std/variant.d. It
was a conflict of an older version of the thing with a newer one (the
lines in conflict were at the recent apply functionality). I'd written
no lines of code in the conflict. It's not impossible I might have
checked out a pull request to look at it. Anyway, my purpose was:
whatever crap is in my master right now, make it the same as the
origin's master.
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).
I get these tidbits of commands - git idioms - all the time, and I
forget them because I don't use them frequently. I don't see why it's a
crime to want to define some macros for such idioms instead of
essentially putting that in a text file that I'd be perusing now and then.
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.
That's pretty much what I wanted but was unable to find easily by
searching the net.
Andrei