I really don't understand why git doesn't create a tag when you rebase in case things go wrong, or more generally when doing potentially gc-able actions.
Pretending the average user will know how to get things back to how they are is silly.
This is technically true, and a common reposte when talking about preservation of history edits.
Unfortunately, the reflog is confusing and hard to use correctly in the case of an interactive rebase with multiple steps. It is hard to figure out exactly how far back you need to go in the reflog to get to moment before the rebase started if you want to start over. It also just so happens that its when an interactive rebase goes awry that I really want to reach for the reflog to fix the damage.
HEAD and the branch have separate reflogs. Each step of an interactive rebase adds a separate entry to HEAD's reflog, but the branch's reflog only ever gets a single new entry when the rebase is complete. So you can run e.g. `git log -g master` and skip the rebase intermediate steps.
It is rather unfortunate that there is no convenient documented shorthand for "show me the reflog of the current branch" (`git log -g` gives you HEAD's reflog). That said, after a bunch of experimentation, it seems like `git log -g '@{0}'` will give you the reflog for the current branch. Apparently this works because e.g. `git log -g '@{2}'` gives you the reflog for the current branch skipping the first 2 elements.
Thanks for pointing this puts I didn’t realize/notice this until recently. And it makes a lot more sense than having one reflog. I would have liked to have known sooner.
> Unfortunately, the reflog is confusing and hard to use correctly in the case of an interactive rebase with multiple steps. It is hard to figure out exactly how far back you need to go in the reflog to get to moment before the rebase started if you want to start over.
When you run git reflog after rebasing, you will see lines like the following:
29d82ac HEAD@{6}: rebase -i (finish): returning to refs/heads/your-branch
29d82ac HEAD@{7}: rebase -i (fixup): Commit message 2
4f8e996 HEAD@{8}: rebase -i (pick): Commit message 2
f3a954e HEAD@{9}: rebase -i (pick): Commit message 1
f74b8a5 HEAD@{10}: rebase -i (start): checkout origin/master
The line listed after the one that has rebase -i (start) is the commit you were on before you started the rebase. If I screw up a rebase, then I will stash any uncommitted changes and run a git reset --hard to the commit listed below the rebase -i (start) commit I see in the reflog and start the rebase again.
Yes, git stash is awesome! I use it all the time to "snapshot" my WIP and/or to quickly get a clean working tree when taking an interrupt to work on something in a different branch. (`gs` alias for `git stash save -u`, along with `grs` for `git reflog show stash` -- which shows the commitish for each stash...)
I see the stash as kind of like a private remote, in that I can freely put whatever messy or experimental or half-baked WIP I like, gaining the benefits of a commit without inflicting it on anyone else.
SmartGit does a brilliant job of integrating the reflog and stashes into the rest of Git. The history log window has a Branches panel, which is a tree view with subtrees for your local and remote branches. Below those is another subtree of any stashes you have saved, and then a Recyclable Commits checkbox.
When you turn on Recyclable Commits, every commit in the reflog shows up in the history tree just like any other commit. You can see exactly where they diverge from your other branches and can work with them as you normally work with any commit.
Same thing for stashes: check one and it just shows up as part of the commit tree as if it were a normal commit.
I've used SmartGit for years and highly recommend it over the Git command line for the way it gives you so much more insight into the state of your repo.
So what are the chances that a version of Git, or something like Git, will be developed that is suitable for the average user? Someone above made a comment about how easy it is to do X in Git, and then preceded to write lines of Git commands that are as arcane as anything an alchemist could come up with. If that is easy Git, I'd hate to see what hard Git looks like.
Making it could be done, Mercurial already exists for example. Perhaps a next-gen version introduced with all the lessons learned over the last decade.
Getting folks to use it would be very difficult due to network effects however.
So true. I live a mercurial life, in a git world. Thanks to hg-git, it is easy to use it and just treat the remote git repository as a black box.
After having rewritten history locally (with Mercurial this is easy, powerful, safe and with a lot of tooling available) everything you need to do is doing an hg push --force.
For one, hg histedit with its curses interface (default since 4.9) is sweet.
Don't hope for git to become something else. Something else will be something else.
In reality, git is actually far from ideal tool, with its own weak points and use-case scenarios which it simply not or badly supports. So it's never "just you" don't feel bad that it's "hard." On top of this, even the scenarios that it supposedly "good" supports demand sometimes totally "illogical" combination of the names and parameters.
git is used in spite of its flaws for different reasons. Some actions are really very fast, faster than by the competition. Sometimes that is a reason enough. Another is -- we have to use what our colleagues use. Even another: once you become familiar with it, even if you were aware of the weirdness, it can stop annoying you. Still to be able to realistically compare it with something else, you have to at least try it. And that something else too.
Something like Darcs is probably going to be the next generation. The nice thing about Darcs is that it records patches in an order independent fashion. This means that you can reorder your commits without penalty. This allows you to remove pretty much all problems requiring ninja-like skills to fix in Git. Darcs, has performance problems on merges, though (as a result of its approach). However, I remember a while ago about someone saying they found a solution to the problem. I think they meant to write a new system, but I can't for the life of me remember what it was called.
Anyway, once you get rid of the actual complexity in git, it's an easy step to work on the added complexity to the UI.
Pijul (https://pijul.org/) is based on a categorical theory of patches (https://arxiv.org/abs/1311.3903). It is similar to Darcs but written in Rust. They claim that Pijul has solved the exponential merge problem. The docs, FAQ, and blogs, in particular the last one, are interesting readings.
Git is really a toolkit for version control. Linus (or some other Git proponents?) distinguishes between "plumbing" and "porcelain": the infrastructure and the UI.
Linus wouldn't claim to be a brilliant designer of user interfaces. It's totally conceivable that somebody could come along and develop a new way of talking about Git's functionality, implemented by a new "porcelain". Changing the vocabulary, creating a more comprehensible map of the internal logic of the thing...