
Git freebase - EricRiese
http://ericrie.se/blog/git-freebase/
======
shazow
The permalink is broken for me (404) but it's still listed on the blog landing
page: [http://ericrie.se/blog/](http://ericrie.se/blog/)

------
avar
The author never elaborates on why exactly he thinks this is needed. I think
reading between the lines the reason is that if someone's done a merge/rebase
and screwed up a conflict resolution the information about how that's happened
is lost forever, so let's come up with some hack to save that information in
case there was a conflict.

If that's the case, a solution that would categorically lose less information
would be:

1\. You're going to push branch you/whatever

2\. You rebase you/whatever on on master

3\. You solve whatever conflicts you have

4\. You make a non-fast-forward merge commit to indicate that you/whatever was
rebased as a series with a name

5\. You push your conflict resolved & rebased you/whatever branch to master

6\. You push the original you/whatever as unrebased/you/whatever

Now you have the original unrebased commits in your repository, you can now
simply inspect your history to see what the original commits were, how they
conflicted, and how those conflicts were resolved.

Once branches in unrebased/* get old enough you just delete them. In my
experience the importance of seeing how someone did something in source
control is inversely proportional to how recently it was committed.

~~~
gkop
In addition to losing less information, your solution allows you to keep merge
conflict resolution off of master entirely (if that's your choice).

~~~
avar
Indeed, but actually much more importantly it doesn't try to "freeze" derived
information that you could just as well construct after the fact from raw
information.

This is a very important general concept in Git. It's reason for why it
doesn't have an explicit "rename" primitive, instead you construct that
information after the fact from the raw history.

Similarly if you're looking to do forensics on merge conflicts it's much
better to have the raw original information.

As an aside, the author also seems to be making the dangerous assumption that
just because the default merge driver doesn't indicate something as
conflicting that he doesn't have to save the original information, his
implementation hinges on `rebaseWithoutConflictsPossible()`.

It's possible to have logical conflicts that Git doesn't detect. E.g. if your
addition of some code uses a function that's been removed from the upstream.

Thus if you really want to cover all these cases just push your original
unrebased branch, then rebase it and push the result (with conflicts, if any,
resolved). That gives you all the information you need for after the fact
forensics, while keeping your history simple for casual inspection.

------
urda
Um, all I see is:

> Oops! That page can’t be found.

> It looks like nothing was found at this location. Maybe try a search?

~~~
EricRiese
Proudly powered by WordPress my ass... It should be embarassed.

------
100k
Reminds me of this (fake) interview with Linus where he points out the "easter
egg" in git:

"Eventually you’ll discover the Easter egg in Git: all meaningful operations
can be expressed in terms of the rebase command. Once you figure that out it
all makes sense. I thought the joke would be obvious: rebase, freebase, as in
what was Linus smoking? But programmers are an earnest and humorless crowd and
the gag was largely lost on them."

[http://typicalprogrammer.com/linus-torvalds-goes-off-on-
linu...](http://typicalprogrammer.com/linus-torvalds-goes-off-on-linux-and-
git/)

~~~
strictfp
This black tshirt attitude is so true. Git simply has zero focus on usability
and actively avoids hiding implementation details. Critizise this and you will
get bashed by the shirts!

Related: [http://git-man-page-generator.lokaltog.net](http://git-man-page-
generator.lokaltog.net)

------
flurdy
Interesting. Basically a commit to remember a conflict when rebasing. Not
entirely my cup of tea as I prefer less noise but helpful for some if
conflicts generate lost work too often. I find it annoying when see commits on
a PR that says "fixing rebase conflicts" etc. "rebase continue" should have
inlined those changes to the relevant commit.

My simpler suggestion to avoid unnecessary merges is to try to wrap an alias
around merge that simple just prompts whether they tried to rebase first. If
you need to merge it often smells like a branch has existed too long.

------
jheriko
i'm pretty sure the simpler answer to this is to always merge, never use a
fastfoward, never rebase and to accept history as what it is instead of trying
to change it to make it 'more manageable' or whatever.

changing the past to make a single linear thread is just weird imo.

depending on what rebaseWithoutConflictsPossible() is doing it might be
helpful though - doing a rebase is an opportunity for the merging algorithms
to cause subtle problems, and taking things out of the context in which they
were actually made reduces the utility of the history for seeing what was
done. the more people you have working on different things at once, the more
likely these problems will manifest as something real. if this
rebaseWithoutConflictsPossible() check is looking for any potential conflict,
not just the ones the algorithms get stuck on then i can see the utility...
but its still not necessary if you never rebase and never fast-forward.

"git recursive merge doesn't screwup x% of merges in some linux kernel repo"
isn't an argument for it being useful in x% of cases so much as an argument
for it causing damage in (100-x)% of cases. the many options available to
tweak its behaviour to make it safer should be a giveaway that the merge
feature is dangerous out of the box... the difficulty of resolving conflicts
and dealing with merges is usually greatly overstated. a lot of programmers
seem to have 'mergephobia'... i'm pretty sure we should just suck it up and do
our jobs - learn that merges aren't that hard, and spend our time thinking
about more important things. :)

------
andrewray
If your branch conflicts, rebase off master (the branch you're making a pull
request to). Then it will merge cleanly. There's no practical downsides to
having merge commits in master, but you should never (or rarely) see merge
conflict resolution commits. You should be able to rebase to a mergeable state
before merge.

~~~
cmwelsh
If you use a pull request workflow then at the very least, you're forced to
merge master into your branch (if there are conflicts) before merging your
branch into master.

You should never (not even rarely) resolve merge conflicts on master...

~~~
gkop
You probably know this but just to be clear, to resolve conflicts on your pull
request branch, you may merge master into your branch _or_ rebase that branch
on master; GitHub makes sense of either kind of resolution.

------
Sidnicious
> Traditional techniques in git are terrible at documenting conflicts.

What's the reason to document rebase conflicts?

~~~
EricRiese
Just the idea that all conflict resolution is fallible and should get a second
look. I don't see why a rebase conflict should be treated differently than a
merge conflict.

------
yakshaving_jgt
How is this different from git-smart?

~~~
EricRiese
I haven't used git-smart, but I read through the docs and it seems that at
it's heart it does a rebase -p which won't ever try to see if a merge can
succeed where a rebase conflicts.

------
jsprogrammer
Where'd it go?

------
thealistra
can you do it as a git alias or a binary you can install as git-freebase?

~~~
EricRiese
I'm working on a bash script now. If it gets popular maybe it will make it
into git flow, or tig, or even git itself.

