@Bulb said in Git is amazing! Or Not!!:
But that still leaves repeatedly merging master into the feature branch. My feature branches often exist long enough that I need the other changes there.
Oh, I absolutely merge from master into my feature branch. Just not the other way; either the entire feature branch gets merged into master in a squash commit, or the feature branch remains separate. (Emergency partial-fixes from a feature branch are really rare; I use the xkcd method there when necessary, with a lot more checking.)
Well, in my case it is pull --rebase unless I am working on the feature branch with other people, with a good measure of git rebase --interactive thrown in, but that's a rather minor detail.
My team started with rebases, but we switched to merges fairly early. Either way, you tend to get merge conflicts if both master and feature branch are fiddling with the same things.
(When things get weird, I always have to go for the xkcd git technique: save my changes elsewhere, create a new branch, copy/overwrite files into new branch.)
By that you are discarding a lot of useful information. Because while git saves states, to put stuff together you should think in terms of changes.
By "weird" I mean "I have typed entirely the wrong commands, in a way that git repositories are prone to." At that point, I have acquired another 50 changes (usually by being careless about which branch I'm in and which branch I'm merging from, modulo some fun with uncommitted changes), and going through the list will take too long. I usually just do a git reset --hard to wherever my "last known good" state is, and go on from there.
This is where the revision range specifiers come in extremely handy: gitk origin/master..
to see my changes to be merged to master, gitk ..origin/master
to see changes on master I did not merge yet, gitk ...origin/master
to see both, git diff origin/master...
to see what a merge to master will look like, git diff ...origin/master
to see what a merge from master will look like. Note that if there is nothing on one side of the dots, HEAD
is implied; you can compare arbitrary revisions that way. Just mind that for pair of revisions (diff) ..
means between the two revisions and ...
means from MRCA, while for range (git log, gitk) ..
means in the second and not the first—so from MRCA to the second similar to the ...
in diff—while ...
means everything that isn't in both—so from MRCA to both.
It is extremely rare for me to get into a "weird" state and not know where I'm supposed to be. (I'm honestly not sure that it's ever happened.) So delving into git magic would only be useful for increasing my hoard of knowledge, rather than actually extracting myself from my predicaments. I suppose the squash-merging-from-master also makes my branch's history pretty simple: everything is either a merge (which must have come from master) or not-a-merge (which must be local).