Imitate rebase to get similar reflog#163
Conversation
| )?; | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
and documentation? If
git reset $(git branch --show-current)@{1}would be enough to "undo" it.
(assuming we had an attached head to begin with, and under Unix; the syntax would be different on Windows) then a big advantage would be that simple instructions can be provided to the users in the README.md and/or git-absorb.adoc.
(and this still might be a candidate for an info log message; I'm not sure if that concept has completely been replaced)
| // If we started out on a branch, update it to point to the result and re-attach HEAD: | ||
| if let Some(branch_name) = branch_name { | ||
| let final_commit = repo.head()?.peel_to_commit()?; | ||
| let branch_name = branch_name.to_string(); // TODO Probably a better way? |
14e6c3a to
536d381
Compare
|
That's a real nice PR description, @sh-at-cs! |
009b6ad to
e14fcd5
Compare
| // To avoid creating entries in our starting branch's reflog when we create commits, | ||
| // we detach HEAD if it isn't already: | ||
| let mut initial_head_ref = repo.head()?; | ||
| let branch_name = if initial_head_ref.is_branch() { | ||
| initial_head_ref.name() | ||
| } else { | ||
| None | ||
| }; | ||
| if branch_name != None && !config.dry_run { | ||
| repo.reference( | ||
| "HEAD", | ||
| head_commit.id(), | ||
| true, | ||
| "absorb (start): detaching HEAD", | ||
| )?; | ||
| } |
There was a problem hiding this comment.
There more I think about this, the more I dislike it:
Unlike rebase, which has to detach HEAD to work, there is absolutely no reason for us to do it other than the reflog.
But the alternative to get to the same result would be to manipulate the reflog, which would probably be even worse, because if something goes wrong, we've destroyed the user's ability to make sense of what happened.
|
Closing because I no longer think this is a good idea: #163 (comment) |
What
This implements the idea from #162 (comment), i.e. we try to make reflog entries created by
git absorblook similar to those created bygit rebase.Why
The original intent of this was to make "undoing" an absorb invocation easier (#157). This change would fulfill that by ensuring the starting branch's reflog only gets a single entry resulting from the
git absorbinvocation, so thatgit reset $(git branch --show-current)@{1}would be enough to "undo" it.But having reflog entries that are similarly clean as those of
git rebasemay also be a good idea beyond that (if nothing else, it certainly looks fancy).How
The easiest way to get reflog messages similar to rebase is to imitate its behavior as well, so that's what we're doing here:
In a similar vein to rebase's initial checkout of the base commit, we start out by detaching
HEAD(if it wasn't detached already). We then perform all our operations in a way that keeps updatingHEAD(in our case: create fixup commits, then rebase if user chose--and-rebase). Finally, at the end, we point the branch we started from (if any) to our final commit and reattachHEADto it.At the points where we update references ourselves (namely: detach
HEAD, point branch to final commit, reattachHEAD), we provide custom reflog messages that follow the format ofgit rebase's.Result
After a successul
git absorb --and-rebase, we have a single reflog entry for our original branch:And the full log of operations bookended by
absorb (...):-prefixed messages inHEAD's reflog:Comparison to
git rebaseJust to expand on what was already said in #162 (comment) and make it easier to compare, after an ordinary
git rebase(not in the context ofgit absorb), we have reflogs like:Typical rebase reflogs
and
Drawbacks & other approaches
Personally, I don't really like that if an error or crash happens in the middle, the user ends up in a detached
HEADstate with no instructions about what to do now. If something like that happens duringgit rebase, Git will at least print some extra information about it ingit statusetc., but I don't think we can imitate that too (?).I'm wondering if it wouldn't be better to keep the same logic as before (i.e. no
HEADdetachment etc.) and only manipulate the reflog after the fact to remove all the extra entries from the branch's reflog 🤔 But that seems like a hack, too...Misc
Fixes #157.