On Thu, Dec 17, 2015 at 06:57:06PM +0300, Konstantin Khomoutov wrote:
> On Thu, 17 Dec 2015 13:16:43 +0100
> Joerg Sonnenberger <jo...@britannica.bec.de> wrote:
> 
> > Now the tricky part is this can be done *without rewriting history*.
> > Essentially, you can (semi-automatically) reapply all changes on top
> > of the new commit and record which commit they were originally. This
> > allows three things:
> > (1) Tight main line with keeping incremental stages.
> > (2) Preservation of what commits originally happened in case you need
> > the full audit trail because there was a subtil merge fault or the
> > like.
> > (3) It allows automated follow-up rebases for 3rd parties that already
> > got the initial changes. I.e. you can safe push your work-in-progress
> > and still transplant it later.
> > 
> > "git rebase" only really allows the first point.
> 
> Not quite.  Well, `git rebase` does indeed replace the tip of the
> branch it operated on with a set of changed commits, but this counts as
> a so-called "drastic head movement" in the Git parlance.  Such
> movements are recorded in the so-called "reflog" ("reference log" --
> with refs or references being heads (branches) and tags), so as soon as
> a rebase operation completes successfully (as opposed to having been
> aborted using `git rebase --abort` where the branch being operated on
> is left intact), you can retreive the previous tip of the affected
> branch from the reflog.  The reflog keeps about 30 days worth of such
> changes by default which is more than enough to cover the "oops!"
> situations.

The very need for reflog and the 30days recovery frame is one of the
saddest part of the git design. It is an arbitrary implementation detail
and not really related to the way "git rebase" works.

> As to "without rewriting history" bit, this might be a terminological
> issue but in a (typical) DVCS you simply cannot cherry-pick or
> otherwise (re-)apply an existing commit to some tip to produce another
> commit without essentially rewriting it because the commit hash includes
> the commit creation date.  And once you've changed a commit's hash, the
> next commit being applied on top of this one will have its hash changed
> also because it will refer to the changed hash-name of its parent
> commit, and this "link" is hashed as well.

The part you are still missing is that the original commit never
got lost. That's why am I talking explicitly about *recreating* and not
*rewriting*. It's like kind of like editing the commit message -- that
doesn't change the original commit either, but creates an update entry
in fossil that just says "well, take that commit, but show *this* commit
message".

> Another point is that when you rebase (or "linearize"), the new upstream
> tip might actually contain changes which will make some or all of the
> commits in the series being rebased/linearized be apply with some
> fuzz, and in complicated cases they might even fail to apply.  In this
> case, even "the contents" (as opposed to metadata) of the
> rebased/linearized commits will be re-written quite literally.  In the
> sense that if you had a commit A on top of upstream's U, and then
> rebased A on top of the updated U' to produce A', the differences A':U'
> and A:U might be substantial.

Yes, some commits might have been getting obsoleted. That's why it can't
be a fully automated process. So you start transplanting the other
commits and either include a dummy entry for nothing at all. Unless the
3rd party was explicitly basing the changes on that now irrelevant
commit, the transplating of their changes can still continue.

Joerg
_______________________________________________
fossil-users mailing list
fossil-users@lists.fossil-scm.org
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users

Reply via email to