[HN Gopher] Git undo: We can do better
       ___________________________________________________________________
        
       Git undo: We can do better
        
       Author : arxanas
       Score  : 507 points
       Date   : 2021-06-21 14:49 UTC (8 hours ago)
        
 (HTM) web link (blog.waleedkhan.name)
 (TXT) w3m dump (blog.waleedkhan.name)
        
       | vzaliva wrote:
       | May I have it in Magit, please?
        
         | snackematician wrote:
         | Magit's wip-mode seems similar in some respects:
         | https://magit.vc/manual/magit/Wip-Modes.html
         | 
         | I haven't tried it, but have been meaning to look into it.
         | Would be curious to hear experiences of anyone who's tried it,
         | and how it compares to the OP.
        
       | kbd wrote:
       | I'll often launch lazygit just to use its undo feature since
       | that's easier than navigating the reflog. Happy to see a
       | standalone utility.
        
       | jldugger wrote:
       | `git-undo` has been part of git-extras[1] for a while. It doesn't
       | use fancy git magic, so maybe this is better.
       | 
       | [1]: https://github.com/tj/git-extras
        
         | skrebbel wrote:
         | It only removes the last commit. It's terribly named IMO,
         | actually, cause I think that's seldomly the kind of thing you
         | get into "omg I messed up how do I undo" panic for.
         | 
         | The undo described here is much more powerful and much closer
         | to what people expect from the word "undo" from its
         | functionality in other tools.
        
       | professoretc wrote:
       | From the article:
       | 
       | > How is it so easy to "lose" your data in a system that's
       | supposed to never lose your data?
       | 
       | I think the author is mistaken; git isn't "a system that's
       | supposed to never lose your data". One of its _features_ is the
       | ability to  "lose" data in a controlled way; i.e., to rewrite
       | history. If you want a version control that is supposed to never
       | lose data, use Fossil.
        
         | arxanas wrote:
         | This is a figurative use of the word "lose", hence the quotes.
         | The beginner comes in with the impression that it's impossible
         | to lose your data with Git, and then manages to "lose" it
         | anyways. Whether it's really lost, or it's just that the user
         | doesn't know how to get it back, isn't relevant from the
         | novice's point of view.
        
         | gpanders wrote:
         | Even if you rewrite history, the data is not lost. The old
         | commits are still in the reflog and can be recovered.
         | 
         | It's extremely difficult to lose anything in Git once it's been
         | committed. You'd have to do something pathological or
         | intentional.
        
           | urxvtcd wrote:
           | It's also possible (if difficult) to recover files which have
           | been git-added and not commited. The only files git can't
           | recover are the ones that it hasn't registered in the first
           | place.
        
       | pjettter wrote:
       | Git should store the commands that "did" the operations on a
       | repo. Git should never ever let you lose work. I should always be
       | able to go "backward" and recover previous states. I guess that
       | is what the "Git undo" proposal is about.
       | 
       | I'm a very visual person so I tend to use Git Graph on VSCode.
       | But I still get in trouble. Especially things like Cherry
       | Picking, or reverting.
       | 
       | Another thing that is not so easy is switching branches without
       | having to do a commit. Stashing, yeah, but then figuring out
       | whether stashes have been applied or not, diffing between
       | branches, picking some changes from a diff.
       | 
       | In the end I stick to some basic commands that don't get me in
       | trouble so that I don't lose half a day to recover my work via
       | Dropbox.
        
         | prisonality wrote:
         | > Git should store the commands that "did" the operations on a
         | repo.
         | 
         | is `git reflog` not enough for your use case ?
        
           | pjettter wrote:
           | No, I mean more like an audit trail. Not like `blame` either.
           | What I typed on the command line to get into a new state.
        
             | sixstringtheory wrote:
             | What about `history | grep "^git"?
             | 
             | Edit to add: the downside is that it only works in the
             | current terminal session. To workaround that for myself, I
             | have a fish shell post exec function that records the last
             | command run, plus a bunch of metadata, to a log file.
        
       | whiddershins wrote:
       | I don't understand. You can always restore any previous state
       | using git, I used to do it from the command line.
       | 
       | If I use github desktop I can roll back a commit whenever I like
       | with a simple menu command.
       | 
       | What am I missing here. I feel like I don't understand what the
       | tool is doing.
        
         | nerdponx wrote:
         | https://github.com/arxanas/git-branchless/wiki/Architecture#...
        
         | whalesalad wrote:
         | If you understand the fundamentals of a version control system
         | I find git relatively intuitive to use. Sometimes I don't know
         | the exact cli syntax for a complicated procedure but that's
         | easy enough to figure out if you know the concepts. Most people
         | fail to learn the concepts and then try to brute force
         | everything.
        
         | jonahx wrote:
         | The README for the parent repo (https://github.com/arxanas/git-
         | branchless) answers these questions in detail.
         | 
         | Short answer, recreating this tool's features in vanilla git
         | requires using the reflog, which isn't user-friendly:
         | 
         | > Why not git reflog?
         | 
         | > git reflog is a tool to view the previous position of a
         | single reference (like HEAD), which can be used to undo
         | operations. But since it only tracks the position of a single
         | reference, complicated operations like rebases can be tedious
         | to reverse-engineer. git undo operates at a higher level of
         | abstraction: the entire state of your repository.
        
       | deknos wrote:
       | i wish the branchless tools would be incorporated in standard
       | git. :|
        
       | vgaldikas wrote:
       | Shouldn't the article be called "We can undo better" :D
        
       | globular-toast wrote:
       | > Here's my theory: novice and intermediate users would
       | significantly improve their understanding and efficacy with Git
       | if they weren't afraid of making mistakes.
       | 
       | Agreed. When I was learning to climb the instructor told me I
       | would never reach my full potential until after the first fall.
       | You cannot work at your limit until you trust the rope.
       | 
       | However, I think this is still avoiding the rope. Git is really
       | simple and when you understand it it's hard to go wrong. I really
       | think what git is missing is a better user interface. Magit is
       | the only one I'm aware of.
        
         | chalst wrote:
         | The easiest way to make mistakes cheap is to have your working
         | directory on a filesystem with automatic snapshots, such as
         | nilfs.
        
       | chagaif wrote:
       | I'm still scared of using got undo
        
       | max_hammer wrote:
       | How hard is
       | 
       | `git reflog` `git reset --hard <SHA of commit you want >`
       | 
       | Or if you just want to move back 1 commit
       | 
       | `git reset HEAD@{1}`
        
         | leifg wrote:
         | git reflog is hard enough so that I (a software engineer for 12
         | years and a git user for 10+ years) have to look up its syntax
         | every time I need it.
        
           | mattkrause wrote:
           | I invariably parse reflog as "re-flog." I know isn't the
           | intended meaning but does capture the feeling of needing to
           | use it quite nicely.
        
           | SamBam wrote:
           | Can you explain what's tricky about it? For me, I just had to
           | remember that "reflog" was the name for "history."
           | 
           | Once I did that, everything else is just regular git
           | commands. Check out a "commit." Revert to a "commit."
        
           | amelius wrote:
           | I think this is the problem with any command which you only
           | need once in a blue moon.
           | 
           | I always forget how to set up networking, because I don't do
           | it often enough.
        
           | juped wrote:
           | Weird, it has no syntax...
        
             | thewebcount wrote:
             | I'm not sure what you mean. Typing "git help reflog" brings
             | up a man page that lists commands like "show", "expire",
             | "delete", etc., each with additional options.
        
         | awb wrote:
         | I say code in my head when I'm thinking through how to approach
         | something. Neither of those code snippets are smooth to recite
         | for something that's a fairly common operation.
        
         | [deleted]
        
         | shadowgovt wrote:
         | I don't think the issue is so much that it's "hard" as that
         | it's "not undo."
         | 
         | As a general rule of thumb, command line tools often ignore
         | decades of UX best practice that have grown up. One of those is
         | that operations (particularly destructive ones) should be
         | easily reversible. It recognizes that human error is common.
         | 
         | And having "undo" specifically recognizes that human error puts
         | the user in an emotional state where restoring things via
         | complex operations is inviting risk. A typo to `git undo` is
         | unlikely to be another command. A typo in the SHA (or an @{2}
         | instead of an @{1}) for `git reset` will compound the error.
         | 
         | ... that having been said, I'm going to go add `git undo` as an
         | alias for `git reset HEAD@{1}` right now.
        
         | sicromoft wrote:
         | I know right? And a monad is just a monoid in the category of
         | endofunctors. What's the problem?
        
         | [deleted]
        
         | arxanas wrote:
         | Sometimes, it's really hard. Using the reflog is like looking
         | through a pinhole.
         | 
         | When recovering from a bad merge conflict, you have a bunch of
         | commits in your reflog which have the same name, and you need
         | to decide which one you want. It's hard to look at the exact
         | diff data and decide which one is appropriate.
         | 
         | It's not listed in the article, but it also enables a workflow
         | where you check out parent commits many times along your branch
         | of development and start new offshoots, and possibly amend
         | commits with many descendants. It becomes nigh impossible to
         | manage the reflog when there are so many commits with the same
         | message but different content. The reflog itself also doesn't
         | make it easy to recover lost descendant commits, only the given
         | root commit.
         | 
         | Other scenarios: the reflog will not help recover where a
         | deleted branch pointed to, and it won't help update multiple
         | branches that pointed to the different positions in the same
         | rebased stack of commits (the reflog for HEAD, anyways).
        
         | happytoexplain wrote:
         | The complexity of executing a solution is irrelevant to the
         | complexity of determining a solution. Regardless, you're being
         | dismissive, and that attitude contributes to the unwillingness
         | of people to ask questions, and therefore hinders learning on a
         | large scale.
        
       | sedatk wrote:
       | I think Mercurial is way ahead of Git on this department by
       | having repositories immutable by default, so even undo actions
       | would have their commit. You never find yourself in an
       | unrecoverable situation. Advanced mutable features can only be
       | accessed by making configuration changes, and are still safe to
       | use because public changesets are differentiated from draft
       | changesets, so, you can only make changes on your own work, not
       | anything else. I mean, you can force it, but that comes with its
       | warnings.
       | 
       | Mercurial has no staging area, and that can be inconvenient for
       | some scenarios; but I think no-staging model is easier to grasp
       | for beginners. I especially think many beginners would assume
       | that modifying a file after it's been added to staging area would
       | update staging area automatically too.
       | 
       | Mercurial has high-level, scenario-oriented distinct "undo"
       | commands like "revert", "forget" and "backout" instead of
       | overloading a single command ("reset") for everything.
       | 
       | I still like `git reflog` though.
        
         | globular-toast wrote:
         | Git is immutable. The only thing that isn't is your working
         | directory.
        
         | umvi wrote:
         | Sounds like mercurial repos would have a lot of "noise" with
         | that approach - commits for fixing other commits spamming
         | everywhere
        
           | capitainenemo wrote:
           | https://www.mercurial-scm.org/doc/evolution/user-
           | guide.html#...
           | 
           | The key thing seems to be the immutable repo editing is
           | hidden by default, but viewable with --hidden flag if you
           | need it.
        
       | jonathanberger wrote:
       | Git is one of those bizarre products that has remained a leader
       | in its category for almost a decade while being extremely
       | difficult to use, even for experts. Another one of these products
       | is Apache.
       | 
       | Why is this?
       | 
       | At least from my naive point of view I would expect these
       | extremely user-hostile products to have been overtaken but more
       | user-friendly alternatives. I know the best products don't always
       | win, but when they don't there's often at least some theory about
       | what is going on (network effects, business partnership,
       | government regulation, etc.) that I don't have with these two
       | products.
        
         | secondcoming wrote:
         | Apache is popular because writing a fully spec compliant HTTP
         | server is actually quite difficult. We use it, I don't like it,
         | but I have enough experience with HTTP to know to not write my
         | own implementation, especially in C/C++.
        
         | MetaWhirledPeas wrote:
         | It has remained popular because it feels like the correct
         | approach in almost every situation, despite having a difficult,
         | obtuse UI. After spending years with Microsoft's centralized
         | version control and then switching to Git it's like a breath of
         | fresh air.
         | 
         | Granted, I almost never use the Git command line and always
         | favor a 3rd party GUI. For users who are a tad confused I think
         | this is the right approach. And to me that's what makes Git a
         | winner: the core software is powerful enough to do everything
         | that needs to be done, and you can pick whatever UI you're
         | comfortable with. No one is forcing you to use Git's built-in
         | UI.
         | 
         | That said I think even the high-level Git concepts have naming
         | that confuses new users. "Pull request" annoyed me for a long
         | time. Yes I _technically_ understood why they chose that term,
         | but practically speaking it just seemed pointlessly misleading.
        
         | leotaku wrote:
         | I would guess that network effects and the amount of quality
         | tools built on top of Git are the main reason for its
         | prevalence.
         | 
         | Fossil and Darcs sure look nice, but having to self-host my
         | repositories or use a smaller company that could go under at
         | any minute? Having to use barely-maintained plugins for my
         | editor, CI, CD, etc.? And most importantly, having to explain a
         | completely new set of tools to anyone who wants to work on my
         | projects? In my opinion, it just isn't worth it.
        
       | cratermoon wrote:
       | It's almost impossible to really lose anything once it's
       | committed to git. Just look at the efforts it takes to really
       | remove accidentally committed secrets.
       | 
       | The hard part is understanding how to get a reference to the
       | thing you want to get back, how to restore it to its proper place
       | in the history, or at least to a reasonable place, and how, if
       | it's been pushed to a shared repo, for other developers to get
       | their local clone properly sync'd up without their local work
       | getting shoved off into some hard-to-reach reference.
        
       | rglover wrote:
       | Calling attention to this which has an undo command and has been
       | very helpful for Git tasks: https://github.com/tj/git-extras
        
       | Jakobeha wrote:
       | Any other recommendations for CLI tools?
       | 
       | I've gotten kind of familiar with the Git CLI. But it took a lot
       | of wasted hours and headaches to do so, and even now it takes
       | headaches and extra time / effort to do certain things like
       | rewrite history and "good" commits. I still prefer CLI to GUI but
       | I wish it was more intuitive.
        
         | jph wrote:
         | Git Alias has many: https://github.com/gitalias/gitalias
        
         | jgilias wrote:
         | There's tig: https://jonas.github.io/tig/
         | 
         | It doesn't have too many features, but the main thing it aims
         | for - a better repo browser, it does really well in my opinion.
        
           | qq4 wrote:
           | I can second tig, it really helps me parse the repo.
        
         | arxanas wrote:
         | You should check out the rest of the git-branchless suite
         | mentioned in the article: https://github.com/arxanas/git-
         | branchless. `git restack` is really useful for some of the
         | rewrite cases. There are some other improvements to rewriting
         | in the devel branch.
        
       | eric4smith wrote:
       | Damn, this is such a GREAT idea. I've messed up repos a few
       | times, and it's never good. It's always -- "what's the magic want
       | I have to wave now"?
       | 
       | The truth is, while we use git every day, most people really
       | don't understand how it works.
       | 
       | There I said it. And I'm not ashamed.
       | 
       | I don't really know how Git works. And I think I'm not the only
       | one.
       | 
       | What does "git reflog" or "git reset --hard ...." do? What are
       | the implications?
       | 
       | We don't really know.
       | 
       | I feel stupid. But hey, at least I'm honest.
        
         | eric4smith wrote:
         | I do use git every single day. It's a super valuable tool.
         | Maybe my bad on not taking a course or reading the manual from
         | cover to cover.
        
         | reacharavindh wrote:
         | +1.
         | 
         | I wonder if it is possible for someone to write a meta-CLI that
         | works on top of git like "git for humans". While, still leaving
         | the power for expert users
        
         | jdmichal wrote:
         | All my git training starts with a whiteboard and drawing out a
         | commit tree and branch pointers. I only talk about the commands
         | in reference to the drawings, not the other way around. Most
         | commands are manipulating this commit tree, so it gives a
         | visual to latch understanding onto.
         | 
         | `git reflog` shows the commits where your current branch
         | pointer has been.
         | 
         | `git reset --hard` moves your current branch pointer and to the
         | given commit, then modifies your working directory to match
         | that commit. `--soft` moves the branch pointer and does not
         | modify your working directory. `--mixed` moves the branch
         | pointer, does not modify your working directory, but does clear
         | staging.
        
         | thatguy0900 wrote:
         | You're not the only one. https://xkcd.com/1597/
        
         | pulse7 wrote:
         | ...plus git operation names are a bit confusing (pull vs.
         | fetch, etc.)
        
         | lisper wrote:
         | I understand how git works, and I still can't use it. There are
         | three problems:
         | 
         | 1. Despite the claim that git never loses data, there are
         | actually some dangerous operations that will irretrievably nuke
         | your work with no warning. Git checkout is the canonical
         | example. This makes me very gun-shy about doing anything that
         | I'm not intimately familiar with.
         | 
         | 2. Git's merge is not smart enough to realize that identical
         | changes in two branches are not actually a conflict. I've often
         | ended up in situations where a small bug has been fixed in two
         | branches which then won't merge without manual intervention.
         | This is incredibly annoying. (To be fair, this is not unique to
         | git. But because git encourages branching more than other
         | systems, I encounter it more when using git in idiomatic ways.)
         | 
         | 3. This is the biggie: translating the abstract idea of what I
         | want to do into an actual git command is a black art. The
         | underlying model is beautiful, but the UI is atrocious. The
         | plumbing is great. The porcelain is cracked and mildewy. There
         | are mysterious valves and pipes all over the place when all I
         | want is one control for the hot water and another one for the
         | cold.
        
           | MereInterest wrote:
           | > that identical changes in two branches are not actually a
           | conflict
           | 
           | I think this is part of a downside of rebase-centric
           | workflows, since it encourages making multiple branches with
           | identical changes, but no shared history. At some point I
           | want to read more pros/cons on different workflows. My
           | current thinking is that rebase-only sacrifices far too much
           | on the altar of a clean-but-inaccurate commit history, but I
           | don't yet know enough to say for certain.
        
             | lanstin wrote:
             | I think if you run into this a lot, git revere will be
             | helpful:
             | 
             | https://www.git-scm.com/book/en/v2/Git-Tools-Rerere
             | 
             | If you have a lot of long-lived branches that don't merge
             | and get deleted you have a whole different world of pain
             | from normal git usage, and need some resources designed as
             | SCM experts to manage this stuff. But really short lived
             | branches that deliver net steps forward are the way to
             | live.
             | 
             | I hate branches because it breaks git-bisect. Linux kernel
             | history has lived without it, so I'm guessing the "our code
             | is so complex we need it" is a false idea.
             | 
             | Also, the actual history of what main/master points to is
             | linear. If the bit-post merge are identical, it doesn't
             | matter if they were rebased or not except having 2
             | ancestors for HEAD is a lie.
        
               | MereInterest wrote:
               | Ooh, rerere looks really nice. I have a few cases where
               | I've needed to repeatedly rebase long-lived branches.
               | (Feature branch A depends on feature branch B, but some
               | small aspects of feature branch B are still under
               | discussion. Feature branch B needs to be occasionally
               | rebased onto main to avoid conflicts, after which branch
               | A needs to be rebased onto B again.). Something that I
               | try to avoid, but that sometimes happens anyways.
               | 
               | Can you explain what you mean by git merge breaking
               | bisect? I've never run into that problem at all. And
               | sure, it might bounce between the branches as you bisect,
               | it still identifies the commit that introduced a bug. The
               | only issue is if one of the commits on the branch fails
               | to compile/test, which is poor commit hygiene, but can be
               | excluded from the bisect.
               | 
               | I still need to do more research, but I think I'd lean
               | toward having a merge workflow, but with no fast-forward
               | commits. That leaves a clean history on main with
               | --first-parent, but still leaves the details available in
               | the branches as needed.
        
               | Shacklz wrote:
               | > Linux kernel history has lived without it, so I'm
               | guessing the "our code is so complex we need it" is a
               | false idea.
               | 
               | Those guys are still sending commits (patches) to each
               | other by mail, I think they willingly live in such a
               | special and weird bubble that it just can't be compared
               | to any "real life industry project".
               | 
               | We've recently started to enforce linear history on our
               | main branches at work, because it makes analyzing broken
               | builds such a breeze. The mantra is "Insertion is hard,
               | analyzing/understanding is easy" (for a merge-based
               | history, it's pretty much the other way around), and so
               | far it's quite the success.
               | 
               | It did take quite a bit of effort though to get everyone
               | up to speed, and it still requires the occasional help to
               | clean up the commit history of some merge request, but it
               | was well-worth the trouble so far.
        
           | atoav wrote:
           | I really would wish git would embrace the idea of not
           | destroying any data unless specifically prompting for it
           | first. Same for merging pull requests. How hard would it be
           | to again prompt in case of conflict how to proceed?
        
             | cerved wrote:
             | Commits are immutable, its incredibly hard to destroy data
             | that has been committed. Even if they become loose objects,
             | Git is very conservative when it comes to deleted that. If
             | you have uncommitted data, git will refuse to do lots of
             | operations. The default is always to not delete changes,
             | even if resetting a branch.
             | 
             | Contrast that with TFVC which tries its best to nuke
             | everything within it's reach (that is not under version
             | control) in inexplicably stupid ways.                 tf
             | reconcile . -r -clean
             | 
             | This command is equivalent to                 git reset
             | --hard origin/head && git clean -fdx
             | 
             | Because that's sensible.                 tf reconcile . -r
             | -i clean
             | 
             | One might think -i is a short flag for -ignore. No. It's
             | short for -preview. That's a "feature". Good luck finding
             | the documentation for this idiotic behavior.
             | 
             | How about if you pipe a list of files into tf reconcile, to
             | avoid it's idiotic behavior? Say                 git ls-
             | tree HEAD -z | xargs -0 tf reconcile -r -clean
             | 
             | You better hope that ls-tree outputs something, otherwise
             | that is the same as calling                 rm -rf .
             | 
             | I can't say I recognize your experience. You only risk
             | creating a mess of changes to the point where it's hard to
             | recover due to the share amount data it hasn't deleted.
        
               | dorian-marchal wrote:
               | Unfortunately, it is still very easy to lose data, e.g.
               | by trying to undo a temporary commit with `git reset
               | --hard HEAD^` (note the --hard option) before committing
               | your changes.
        
               | AlexSW wrote:
               | Agreed. I consider myself pretty competent at git
               | (consistently helping out the rest of my team of ~15
               | people with it) and even then I've shot myself in the
               | foot using `git checkout --` instead of `git reset`
               | before to unstage a file, and lost all of my work on it.
               | Really felt that should have given a warning.
        
               | cerved wrote:
               | use git stash instead to unstage changes not committed to
               | the index and you'll never lose anything ever again
        
               | unknown_error wrote:
               | The point is that you shouldn't have to learn everything
               | by brutal trial and error, losing hours of work each time
               | you try to learn a new operation and make a small
               | mistake.
               | 
               | It's the same reason consumer operating systems have a
               | trash can and undo features. Just railing on people with
               | "you should've known better" doesn't really help.
        
               | cerved wrote:
               | That's why it's a flag. You could do git reset HEAD^ &&
               | git stash instead
               | 
               | Also, git reset ---hard HEAD^ deletes nothing. The commit
               | HEAD was pointing is not deleted. You have to work really
               | hard to delete that commit accidentally
        
               | glandium wrote:
               | It does delete whatever uncommitted changes you had.
        
           | grogenaut wrote:
           | the recommendation is actually used a different algorithm for
           | the language that you're working in so I just use beyond
           | compare and 99% of my simple conflicts or Auto resolved. It'd
           | be better if these algorithms were just built into the sea
           | Alli itself but they decided in unix style to delegate
        
           | arxanas wrote:
           | There is a design for undoing changes to the staging area:
           | https://github.com/arxanas/git-branchless/issues/10
           | 
           | The similar project
           | [Jujube](https://github.com/martinvonz/jj) has experimented
           | with backing up even unstaged changes after every command,
           | and apparently it works well for them, so we could do the
           | same in the above design.
           | 
           | Undoing even untracked changes might be a bit much.
        
             | lisper wrote:
             | Yeah, this barely scratches the surface though.
             | 
             | Take branching, which is something you're supposed to be
             | doing all the time. So abstractly, I want to be able to get
             | a list of my current branches, create a new branch, check
             | out an existing branch, delete an existing branch, and
             | maybe rename a branch. I would expect the commands for
             | these operations to be something like:
             | git branch list         git branch create [name]
             | git branch delete [name]         git branch rename [old-
             | name] [new-name]
             | 
             | We can argue over whether checking out a branch should be
             | "git branch checkout [name]" or just "git checkout [name]",
             | but in either case, if I have unsaved changes in my working
             | directory, I would expect to at least get a warning about
             | this before that work got clobbered.
             | 
             | None of these things are actually the case. Git checkout
             | will clobber unsaved changes in my working directory. "Git
             | branch list" is just "git branch". "git branch create" is
             | "git branch [name]". So creating a branch is the SAME
             | COMMAND as the one you use to produce a list of current
             | branches, just with an argument. Madness. And this is the
             | rule, not the exception. Minor variations on a theme can
             | result in radically different commands with various
             | mysterious arguments. There is no rhyme or reason or
             | regularity. The only way to know is to look it up.
        
               | atoav wrote:
               | Checkout should be _load_ or _open_.
        
               | akersten wrote:
               | > Git branch list" is just "git branch". "git branch
               | create" is "git branch [name]". So creating a branch is
               | the SAME COMMAND as the one you use to produce a list of
               | current branches, just with an argument. Madness. And
               | this is the rule, not the exception.
               | 
               | As a counter-opinion, I actually like it this way.
               | Especially since it's the rule and not the exception.
               | When one makes the small effort to learn the commands,
               | the payoff in saved keystrokes from avoiding typing the
               | redundant pieces is great.
               | 
               | As a painfully simplified justification: Directory
               | listing is "ls" and removing a directory is "rmdir" - I
               | much prefer that to typing a hypothetical "directory
               | list" and "directory delete", even if the later fits some
               | nice consistent shape.
               | 
               | It's one of the reasons I hate powershell/windows-style
               | CLI and its 60-character long arguments for every
               | function.
        
               | lisper wrote:
               | There's nothing wrong with having a UI for power users in
               | addition to a more intuitive one. But having a power-user
               | UI as the only option (or even as the default) is not so
               | good.
        
               | seoaeu wrote:
               | In particularly well designed UIs, the interface for
               | power users and the intuitive one are one and the same!
        
               | munificent wrote:
               | _> "git branch create" is "git branch [name]"._
               | 
               | I've been using Git professionally for of a decade and
               | you just taught me something new. I always use `git
               | checkout -b [name]` (which is a completely bananas UX,
               | but it's the one I know).
        
               | seoaeu wrote:
               | The two commands aren't actually equivalent, because of
               | course they're not. Usually when you create a new branch
               | you'd like to switch to it, but _git branch [name]_
               | actually doesn 't do that, so you have to execute a
               | second command after.
        
           | IshKebab wrote:
           | > The underlying model is beautiful, but the UI is atrocious.
           | 
           | I definitely agree. The UI is terrible. But it is learnable.
           | 
           | I would recommend using a GUI initially so you can learn what
           | the operations are and do without having to figure out that
           | it's not `git remote list` it's `git remote -v`; it's not
           | `git clean` it's `git checkout . && git clean -fdx` and a
           | million other paper cuts.
        
         | jozvolskyef wrote:
         | Have you tried reading the manual[1]? I read it cover to cover
         | once and it is invaluable because it gives you the ability to
         | understand and describe what you're trying to achieve. The
         | solution is always one search away if you know how to ask.
         | 
         | [1]:
         | https://mirrors.edge.kernel.org/pub/software/scm/git/docs/us...
        
         | sngz wrote:
         | this is why i was so sad when mercurial support ended. I loved
         | using mercurial it just works and it was so intuitive. My firm
         | last year switched all projects over to github and it's been a
         | pain, I learned it no problem but still have to google the
         | occasional thing, but I spend most of my time fixing other
         | people messing up the repo.
        
         | sebmellen wrote:
         | For some reason people love to defend the obscure and strange
         | and oftentimes objectively terrible Git CLI. I've found
         | Mercurial much more straightforward for my (mundane and boring
         | but prevalent) use cases, and I lament that it isn't more
         | widely used.
        
           | zibzab wrote:
           | Every single time we are discussing git this comment shows
           | up.
           | 
           | But why is one popular when the other one is so much better?
           | I guess we will never know
        
             | _ph_ wrote:
             | There are several reasons. In the beginning, hg was
             | critisized to be slow as it was written completely in
             | python. The effect of the Linux team going with Git instead
             | created a lot of attention to git, probably also a lot in
             | people who were faszinated by the capabilities of git and
             | did not care much about user friendlyness. The biggest push
             | for git undoubtedly came from github. That is now the
             | premier platform for hosting software, especially open
             | source software.
        
             | lanstin wrote:
             | This also shows that quality of the technology matters.
             | Like the discussion on the business value of Amazon's "use
             | APIs always," using git is using a superior source code
             | technology, designed from the ground up for distributed
             | development by a master of distributed development; good
             | things are enabled automatically. Linus' naming and UX
             | choices and inconsistencies aside, the tool is awesome.
             | That's why it wins in distributed development environments
             | - the bazaar not the cathedral and not the bespoke
             | engineering team hidden away in the corporation.
        
             | ryandrake wrote:
             | Although it sounds like a silly reason, compare the names
             | themselves. I don't even know how to pronounce "mercurial"
             | without looking it up. The word doesn't exactly roll off
             | the tongue like git does. And then the command itself is
             | "hg". WTF is up with that? I mean, ha-ha we all get the
             | joke, but was the program made for chemists? Unnecessarily
             | clever. Don't underestimate the extent to which a
             | difficult/confusing name/brand can harm adoption.
        
               | j605 wrote:
               | I think for most people, they would encounter it in a
               | science class early in life (at least for English
               | speakers). And Hg is just the chemical symbol for
               | mercury, https://pubchem.ncbi.nlm.nih.gov/element/Mercury
               | #section=Ide...
        
               | zabzonk wrote:
               | > I don't even know how to pronounce "mercurial"
               | 
               | But you do know how to pronounce "Unnecessarily"?
        
             | marcosdumay wrote:
             | That is solely because of network effects. Anyone of them
             | could be the popular one, as could any of the weirder ones
             | like darcs, even it having technical flaws (mostly fixed by
             | now).
        
             | disgruntledphd2 wrote:
             | GitHub is the reason. Turns out giving beer to developers
             | globally is an effective way to get a technology adopted.
        
               | zabzonk wrote:
               | Bitbucket used to provide free (and pretty good)
               | Mercurial hosting.
        
               | oblio wrote:
               | Bitbucket had a much crappier UI.
        
               | zabzonk wrote:
               | Actually, one of the reasons I preferred hg to git is
               | that Windows explorer GUI integration back then was far
               | superior to gits, which was buggy as hell.
        
               | ivanbakel wrote:
               | This doesn't seem relevant to the comment you're replying
               | to. Bitbucket's web UI sucks, which is why it didn't have
               | the effect on Mercurial that Github had on git.
               | 
               | Having used Bitbucket and GitHub, I think GH is much
               | nicer - both in the sense of basic stuff like page loads
               | being faster, and in terms of features. And since it's
               | the main tool that everyone on the development team
               | spends their time on for communication & collaboration,
               | those things really matter.
        
               | mixmastamyk wrote:
               | Also, remember to compare the sites ten years ago rather
               | than today.
        
             | zabzonk wrote:
             | The Torvalds effect.
        
               | zibzab wrote:
               | I know you imply, but this could also be interpreted as
               | "battle proven" or how about "guaranteed to still work in
               | 30 years"
        
           | grogenaut wrote:
           | Personally I think it just needs a 3.0 where they completely
           | rename all the commands so that they're really unified. I
           | know there was pushback on this in the past
        
             | seoaeu wrote:
             | The thing with command line interfaces is that since the
             | same interface is used by humans and computer scripts, you
             | essentially end up with an unversioned API that you can
             | never make breaking changes to.
        
               | symlinkk wrote:
               | It is versioned. There is git ---version. If your scripts
               | break with the new version, don't upgrade.
        
             | matheusmoreira wrote:
             | That would be nice but will probably never happen due to
             | backwards compatibility. Breaking changes in git would be
             | even worse than the slow switch to Python 3.
        
               | lanstin wrote:
               | Just call the consistent one "ggit" and the inconsistent
               | one "git."
        
           | cerved wrote:
           | The UX philosophy is radically different. One presupposes
           | that you understand a lot more of the underlying system. The
           | other tries to focus on what it is what you want to do, as
           | opposed to how.
           | 
           | Mercurial is less intimidating if you don't know much about
           | internals. But tbh, when I use Mercurial I still find myself
           | searching which command to do things. As a frequent power
           | user, I find the Git CLI to be more useable.
        
         | SkyPuncher wrote:
         | > The truth is, while we use git every day, most people really
         | don't understand how it works.
         | 
         | I once knew how it worked with moderate level of detail, but I
         | simply do not need anything advanced for my day-to-day work.
        
           | carlosf wrote:
           | Yeah that's my issue as well. I generally forget anything I
           | don't use often and git is full of important stuff that you
           | need infrequently.
        
             | lanstin wrote:
             | It's very simple, it's a graph, and you can reason what
             | changes you want to make to the graph, and then google for
             | the commands. Re-writing history is really only reserved
             | for binary checkins, and that task should be assigned to
             | whomever checked them in, so you should never need to do a
             | destructive change. Even credentials checked in should be
             | rotated so they aren't valid, not re-written.
        
         | handrous wrote:
         | I know (or, at least, _have known_ ) how git works, in the way
         | most people mean that (the data structures & on-disk layout,
         | what a commit is, what a tag is, what a branch is, what HEAD
         | is, staging, et c.). What I can't keep straight is WTF the
         | commands are actually doing, in that low-level sense, which is
         | a different thing, and there's approximately a 0% chance I'm
         | ever going to use more than a tiny fraction of the commands
         | often enough to remember that information.
        
           | anoncake wrote:
           | Maybe for low-level, somewhat rare tasks the ideal Git
           | porcelain would be a GUI that just exposes the data model
           | directly.
        
           | skeeter2020 wrote:
           | YES! you learn the happy-path commands you use all the time
           | and the handful of "sadder-path" approaches you try when
           | things go south, but there is a dramatic fall-off in
           | knowledge and understanding from there that leaves otherwise
           | clever and confident people feeling stupid and frustrated.
           | This is not a silver-bullet for productivity but still a very
           | worthy problem to address that could have meaningful impact
           | for a lot of people.
        
           | Vinnl wrote:
           | I'm the same, but I think that's... Fine? If I understand
           | what I want to do in terms of first principles, there's no
           | harm in searching for the exact incantation if I do that only
           | once every few months.
           | 
           | For the rest, there's shell autocomplete and muscle memory.
        
           | dheera wrote:
           | Yes. Especially
           | 
           | git init --submodule --recursive
           | 
           | Or is it
           | 
           | git submodule --init --recursive?
           | 
           | God I hate this UX so much I usually have a ./fetch-
           | subrepos.sh that runs a bunch of "git clone" commands.
           | 
           | And if I push without first pulling, must it always punish me
           | with a merge commit? Can't I say "oh shit I don't want to do
           | this, go back and git pull"?
        
             | ItsMonkk wrote:
             | It is for this reason that I have changed my workflow to
             | always stash first, then pull, then pop the stash and do
             | the merges locally, then push.
        
               | [deleted]
        
               | lanstin wrote:
               | And always diff before stash because sometimes it's just
               | random shit I wasn't serious about, so I'll re-checkout
               | that file and then stash the rest.
        
             | urxvtcd wrote:
             | > And if I push without first pulling
             | 
             | I think I know git well, but you got me confused. I've
             | never heard of pushes causing merges. Surely you are
             | talking about pulls, right?
        
               | kahmeal wrote:
               | push causes the error, the resolving pull creates the
               | merge; the correct resolution has been pointed out as git
               | pull --rebase but most people don't realize this.
        
               | MereInterest wrote:
               | Maybe somebody who has a habit of using --force when
               | pushing. A major downside of rebase-centric workflows is
               | that it teaches you to ignore the safety rails when
               | pushing, or when deleting branches.
        
               | Zarel wrote:
               | `--force-with-lease` would fix this problem (it needs an
               | alias). Also, `--force` wouldn't cause a merge commit; it
               | would overwrite the remote changes.
               | 
               | The only theory that makes sense is that this person
               | doesn't know how to `pull --rebase`, but the order of
               | `push` vs `pull` wouldn't change the presence of merge
               | commits, so I'm still confused.
        
               | jtbayly wrote:
               | I don't know git well, but I often run into the problem
               | being discussed.
               | 
               | If I pull from origin before making my changes, I don't
               | have to merge, obviously.
               | 
               | But correct me if I'm wrong: I think that if I don't pull
               | first, but my changes don't conflict with any part of
               | what was done by the previous commit(s) I missed, I'll
               | still have to merge if I touched a file they touched.
               | 
               | This is a common scenario for me. Correct some typos in
               | comments for example, and I get forced to figure out how
               | to merge using vim, which I don't know how to use at all
               | (being a nano user). I'm sure I could and should switch
               | to at least using nano by default, but I don't know how
               | merging really works, either.
               | 
               | What I really want to do is undo my commit, pull, and
               | redo my commit. Then I don't have to figure out git
               | merge.
        
               | Zarel wrote:
               | > I don't know git well, but I often run into the problem
               | being discussed.
               | 
               | I do understand the problem being discussed; what I don't
               | understand is what it has to do with pushing first. You
               | have the same problem no matter which order you use `git
               | push` vs `git pull`.
               | 
               | > I think that if I don't pull first, but my changes
               | don't conflict with any part of what was done by the
               | previous commit(s) I missed, I'll still have to merge if
               | I touched a file they touched.
               | 
               | Yes, that's true.
               | 
               | > What I really want to do is undo my commit, pull, and
               | redo my commit. Then I don't have to figure out git
               | merge.
               | 
               | You can do that with `git pull --rebase`, which, as
               | others have mentioned, you can set as the default
               | behavior of `git pull` like this:
               | 
               | https://news.ycombinator.com/item?id=27581416
        
               | MereInterest wrote:
               | Ooh, --force-with-lease looks like a nice feature,
               | especially for updating github PRs that aren't yet
               | merged. I still wouldn't want to use it where anybody
               | else has a copy of the changes, since that's where you
               | need a merge commit to avoid breaking somebody else's
               | repo, but that gives me a safer option than a blind
               | --force.
        
               | pjc50 wrote:
               | Wait, what? I've probably been using Gerrit too long but
               | why do you ever need force in a rebase workflow?
        
               | MereInterest wrote:
               | These may be specific to a workflow with git + github,
               | when using git from the command line, but here are the
               | cases I've run into where overriding safeties is needed.
               | 
               | 1. After making a PR, there are conflicts when merging
               | into main. In a merge-based workflow, I would merge main
               | into the feature branch, resolve any conflicts, then
               | push. In a rebase-based workflow, I rebase the branch
               | onto main, resolve any conflicts, but now I need to push
               | --force. As some of the other comments have mentioned,
               | this can be improved with --force-with-lease, but still
               | isn't the greatest.
               | 
               | 2. After making a PR, there are some typos that need to
               | be fixed. Fix these in an interactive rebase, to edit the
               | same commit that introduced the typos. Also requires
               | either --force or --force-with-lease.
               | 
               | 3. When the PR is accepted, the result is rebased on top
               | of main. My local branch still exists, and must be
               | deleted. I would prefer to use `git branch -d` to delete
               | the feature branch, but this rightfully says that the
               | feature branch hasn't been merged in. I instead need to
               | use `git branch -D` to forcefully delete it, introducing
               | a point of human error. (There are some cases where git
               | can delete the branch safely, which I _think_ occurs
               | either when the feature branch has only a single commit,
               | or when the feature branch can be applied on top of main
               | without a rebase, but I haven 't exactly determined it.)
               | 
               | #1 and #3 are cases where a safer option cannot be used
               | due to a rebase-workflow. #2 would exist in either case,
               | since even in a merge workflow, rebasing of branches
               | before they are pulled makes sense to do.
        
             | handrous wrote:
             | > And if I push without first pulling, must it always
             | punish me with a merge commit? Can't I say "oh shit I don't
             | want to do this, go back and git pull"?
             | 
             | This is a source of probably 50% of my "ah, fuck, time to
             | undo..." moments with git, these days. I hate that shit.
             | Muscle-memory gets ahead of me and I commit on a shared
             | remote branch, which would be fine given our workflow
             | except that I didn't pull first. What a pain in the ass.
        
               | Nullabillity wrote:
               | For the sake of your coworkers (and your future self),
               | please don't lie just to make your history look pretty.
        
               | lamontcg wrote:
               | I guess I have `git pull --rebase` as muscle memory.
               | 
               | I would guess there's an easy way to make git do this
               | automatically for you via config so you never forget, but
               | I just never, ever `git pull`
               | 
               | Or:
               | 
               | > git config --global alias.up '!git fetch && git rebase
               | --autostash FETCH_HEAD'
               | 
               | From:
               | 
               | https://github.com/JKrag/git-up
        
               | [deleted]
        
               | rjmunro wrote:
               | git config --global pull.rebase true
               | 
               | You probably also want:
               | 
               | git config --global rebase.autostash true
        
               | [deleted]
        
               | funkymike wrote:
               | I have this in my .gitconfig so the pull will fail rather
               | than merge.                   [pull]             ff =
               | only
               | 
               | If it does fail I can decide whether to merge or rebase.
        
             | lugged wrote:
             | Git init inits a git repo.
             | 
             | Git submodule runs commands on submodules.
             | 
             | What is hard about this UX?
             | 
             | And it's not punishing you, its doing what you asked, to
             | pull into a non matching head, how does it know you're not
             | using git in the intended and distributed way?
             | 
             | Btw, just quit the editor without saving, it aborts.
        
               | pjc50 wrote:
               | The "intended" way generates a completely spurious merge
               | commit - it doesn't represent a real commit, and rarely
               | do you care about keeping track of merges into a short
               | lived branch which are already tracked on master.
               | 
               | Most people want a single source of truth workflow that
               | corresponds to the old total ordering imposed by svn or
               | p4.
        
               | klyrs wrote:
               | [misunderstanding removed]
        
               | smichel17 wrote:
               | In a thread about common sources of confusion, I think it
               | would be more helpful to leave the misunderstanding so
               | others might learn from it. Ie, edit to add "this is a
               | misunderstanding" to the top, not replace it entirely.
        
               | chakspak wrote:
               | You can also quit the CLI editor, e.g. vim.
        
               | chriswarbo wrote:
               | Git invokes an editor, for writing commit messages, etc.
               | (it looks in the VISUAL and EDITOR env vars). That could
               | be a GUI text editor, or something running in the CLI
               | (personally, I use emacsclient to open a new buffer in an
               | existing Emacs window)
               | 
               | What they're saying is: if you quit that editor without
               | saving the commit message, git will abort.
        
               | handrous wrote:
               | I think they mean the commit message editor, which git
               | will use to open a temp file to save the message to if
               | you don't specify a message in-line with the "-m" flag
               | when committing, including when a merge commit is
               | initiated by a "pull". This happens on the CLI, it's just
               | usually (though doesn't have to be!) a command line
               | editor that it opens. I think vim's a common default.
               | 
               | AFAIK whatever's opened does need to block the CLI, so
               | you can't use a command that opens a GUI editor then
               | returns immediately or git will interpret that as your
               | having closed the file without saving, but otherwise any
               | editor should work, CLI or GUI, and can be assigned in
               | your git config.
        
           | stormbrew wrote:
           | definitely agree, and I'm in the same boat. I don't even
           | think the data model of git is that hard to grok at all, it's
           | mostly that commands are very unclear on what they operate on
           | and in particular people get really tripped up about how many
           | levels of state there are (stage, working tree, local
           | branches, remote refs) that they have to interact with.
           | 
           | Like, I've had to explain a lot of times why you `git pull
           | origin master` but when you want to interact with that remote
           | branch otherwise it's `origin/master` instead. The lack of
           | clarity is in what commands operate on what levels, with many
           | of them operating on several at once.
           | 
           | There have been some efforts to reform the command set to be
           | more clear, like `git switch`, but the old commands will
           | persist forever along with a lot of other footguns (like `git
           | push --force` really ought to be replaced with `git push
           | --force-with-lease` and moved to `git push --force-I-really-
           | mean-it` so it hardly matters.
        
             | ethbr0 wrote:
             | > _levels of state_
             | 
             | This is the crux for me. Command naming is completely
             | unrelated to and unindicative of state.
             | 
             | It feels like surely there's an opportunity for the basic
             | CRUD operations to be collapsed down into a standard
             | "{action} {source} {target}" style.
             | 
             | There will be nuances, specifically around branching, but
             | the basics should be basic. As opposed to a Swiss Army
             | knife, where you have to pull out the scissors and squeeze
             | them three times before you can unfold and use the blade.
        
               | ryanmentor wrote:
               | Are there any git frontends that do this today?
        
               | unknown_error wrote:
               | The one built into IntelliJ IDEs is pretty good.
               | SourceTree is decent too. They are both cover the vast
               | majority of day to day operations. I only ever very
               | rarely have to resort to the command line for ritualistic
               | summoning of the git demons.
        
             | stickfigure wrote:
             | I've actually worked on git internals and I'm in the same
             | boat.
             | 
             | As part of a security-related project some years ago, my
             | team and I hacked jgit to use SHA256, which required
             | changing the length of pretty much every on-disk data
             | structure. Sadly, there was (probably still is) no HASH_LEN
             | constant, just a lot of magic offsets strewn throughout the
             | code. I had to compare lengths against the git spec at
             | every step.
             | 
             | And yet I still scramble for stackoverflow every time
             | something goes slightly amiss.
        
               | davvid wrote:
               | There's an ongoing effort to rework core Git so that the
               | hash implementation can be swapped out for eg. SHA256.
               | [1]
               | 
               | jGit is actually a separate project from core Git, but
               | once it gets adopted into core Git we can expect that
               | jGit will follow suite, given that it's critical to
               | Gerrit and other projects.
               | 
               | [1] https://lore.kernel.org/git/20191223011306.GF163225@c
               | amp.cru...
        
               | sam_lowry_ wrote:
               | What a pointless project! U hope you were paid well, at
               | least.
        
               | stickfigure wrote:
               | I was. But it wasn't _quite_ as pointless as it sounds -
               | the tool was a sort of tripwire-like system, with changes
               | shipped to an append-only log, that itself was
               | checkpointed in an early blockchain-ish structure. The
               | threat model was  "nation state actor" so the client
               | wouldn't accept SHA1.
               | 
               | It was actually a pretty cool system. I don't think it
               | was ever sold though.
        
               | unknown_error wrote:
               | Man, I thought zero days and secret backdoors were bad
               | enough. Now we have to worry about manufactured hash
               | collisions in all our repos' files dating back forever?
        
               | simonelnahas wrote:
               | That seems like an overkill. Couldn't you combine the
               | hash together with the date to obtain uniqueness?
        
               | unknown_error wrote:
               | The date isn't really meaningful since it can be set to
               | anything on a file. But if you can force two dissimilar
               | files to have the same hash, you can combine that with
               | some other attack to inject it into some sort of chain of
               | trust, whether it's git or some other type of checksum
               | based system. Then combine that with a SolarWinds like
               | attack and even if they try to revert to something from
               | years earlier, they can't guarantee that the rollback
               | files are still unaltered unless they had multiple hashes
               | to compare it to or diffed it manually. But multiply that
               | by X thousand files over Y commits during Z years and it
               | would be very difficult to detect.
        
             | fierro wrote:
             | can you explain the `git pull origin master` thing one more
             | time here?
        
               | stormbrew wrote:
               | like why it's different?
               | 
               | `git fetch` (and by extension `git pull` when given a
               | remote) and `git push` copy data to and from a remote.
               | When you specify `git pull origin master` you're saying
               | "pull down a copy of the remote ref master from origin",
               | which it then saves locally as the ref `origin/master`.
               | 
               | Everything under `origin/ _` (or really `refs
               | /heads/origin/_`) is just a cached pointer to the last
               | known state of that ref on the remote.
               | 
               | All other commands operate only on these local
               | references. So when you want to refer to what you know to
               | be the state of things on `origin`, you can use
               | `origin/master`. Otherwise that command has no particular
               | knowledge of how to talk to origin.
               | 
               | Incidentally this is a shortcut I use all the time to
               | update my local master from a remote:
               | 
               | `git fetch origin master:master`
               | 
               | Which is super unclear in its meaning but it means fetch
               | origin's master HEAD and put it in my local master ref. I
               | actually use this more often than git pull nowadays.
        
               | nicoburns wrote:
               | I tend to default to `git pull --rebase`.
        
               | pjc50 wrote:
               | I have this configured as default everywhere and strongly
               | believe that merge-pulls are always wrong. The first
               | place I used git we were learning together (i.e. nobody
               | knew what a sensible workflow was) and people would push
               | their local merge commits back to master. It was
               | horrible.
        
               | stormbrew wrote:
               | `git config merge.ff=only` is really helpful for
               | enforcing this. It makes you have to say what you want
               | for any non-trivial update of a ref through pull or
               | merge.
        
               | [deleted]
        
               | dorian-marchal wrote:
               | Also, one advantage of `git pull origin master:master` is
               | that you don't have to checkout master first.
        
               | mbeex wrote:
               | > (or really `refs/heads/origin/`)
               | 
               | It is worth the time to fully understand refspecs. Once
               | people do, they tend to understand all essential
               | ramifications of branch and repository naming.
        
               | usr1106 wrote:
               | I don't think using `git pull` is a particular good way
               | of working. A pull is a fetch and merge or a rebase
               | combined.
               | 
               | If it's difficult to keep your mental model of some
               | system up to date, I doubt that doing bigger steps at
               | once makes things easier.
               | 
               | So
               | 
               | 1. run `git fetch`
               | 
               | 2. if the textual output does not tell you what has
               | happened, run `gitk -all`
               | 
               | 3. Decide what to do. Rebase, merge, whatever.
               | 
               | Of course if you know exactly what you are doing, pull
               | can be fine. If you changed the repo yourself on another
               | computer that is the case. Otherwise, how can you know
               | your second step, before having even seen the data you
               | are operating on? Well, it _can_ work, but if it doesn
               | 't, don't complain.
        
               | xorcist wrote:
               | This is literally the first advice I give when teaching
               | people git. The first months of use, just run the two
               | commands separate. Many mistakes are avoided that way.
        
               | u801e wrote:
               | > I don't think using `git pull` is a particular good way
               | of working.
               | 
               | I agree. For a DVCS like git, separating the network
               | transaction from updating the working copy on disk is the
               | best way to go about it. Going in the other direction,
               | this is the default since git add, git commit and git
               | push are executed separately.
        
             | mikepurvis wrote:
             | What's wrong with `git push -f`? When I'm working on a
             | branch that's been previously pushed with `-u`, it's pretty
             | normal to force push it, particularly if you're amending or
             | reordering commits in response to review feedback, or
             | rebasing due to conflicts in preparation to merge.
        
               | stormbrew wrote:
               | changing `-f/--force` to act like `--force-with-lease`
               | would have no effect on that flow whatsoever. What it
               | would prevent is you accidentally overwriting something
               | on the remote because you didn't know its current state,
               | potentially silently backing out changes someone else (or
               | perhaps you yourself on another machine) had pushed.
               | 
               | All it does is add this simple check before actually
               | pushing:                   if (remote_ref("blah") !=
               | local_ref("remote/blah"))             fail();
               | 
               | Most of the time it doesn't matter, and for most people's
               | uses of --force it would have no effect (because most
               | people are just pushing to a branch they're the only one
               | pushing to). But every now and then it helps a lot to
               | avoid losing data.
        
           | zoomablemind wrote:
           | I wonder should Undo as a concept apply to all Git
           | actions/commans which have state side-effects on the repo or
           | work dir OR should Undo only cover certain operations (which
           | ones)?
        
           | Filligree wrote:
           | Take a look at https://eagain.net/articles/git-for-computer-
           | scientists/?
           | 
           | Maybe you've already read it, but this is what let _me_ grok
           | the underlying data.
        
             | romwell wrote:
             | I think the parent commenter says that they _do_ understand
             | the underlying data.
             | 
             | It's just that the command-line interface is very opaque
             | regarding what it does to that data.
             | 
             | For instance, say I want to apply the last three commits I
             | made in one branch to another branch. It's a very simple
             | operation conceptually.
             | 
             | Good luck remembering that the command that does it is
             | _rebase_ , and what the arguments for it are.
        
             | cxr wrote:
             | The parent commenter makes it clear that they already grok
             | the underlying data. The problem with Git, as explained so,
             | so many times, is its horribly intuitive mapping from UI to
             | the operations those commands preform on that model.
             | 
             | Comments like this, which points to a resource intended to
             | help people "grok the underlying data", has the effect of
             | seizing the focus of conversation and implicitly
             | retargeting it to be concerned with with people who _don
             | 't_ understand the underlying data model. When you been
             | through this enough times, it just comes off as incredibly
             | annoying and a source of tiresomeness.
        
         | pizza234 wrote:
         | Are you using Git via GUI(s)?
         | 
         | Between my colleagues, there is a strong correlation between
         | using a GUI, and messing up the repository.
         | 
         | I agree that Git's UX is pretty bad (checkout overloading;
         | overlapping between checkout and reset; push overloading...
         | yikes!), however, I believe that in contexts where using Git is
         | a constraint, stop using GUIs is the best strategy one can
         | apply to improve the understanding.
        
           | woah wrote:
           | Sorry, I'm trying to get work done, not memorize an obscure
           | set of incantations like some kind of D&D wizard. If the repo
           | gets messed up, I delete it and reclone.
        
             | cerved wrote:
             | It's a handful of commands, very well documented with tons
             | of SO questions that is one search away if you can figure
             | it out yourself.
             | 
             | It's something I use all day, every day. I'd say it's
             | worthwhile to learn if your daily job involves working
             | under source control
        
               | tailspin2019 wrote:
               | Yes I agree. If you're going to use git (whether by
               | choice or force) it is 100% worth learning the small set
               | of commands required to undo a screwup without needing to
               | reclone.
               | 
               | Recloning to me is a bit like tearing your house down and
               | rebuilding it just because you painted your living room
               | the wrong colour (in most cases!)
        
             | Shacklz wrote:
             | I really understand your sentiment, and I've been there for
             | long enough myself - but once you have a somewhat decent
             | understanding about gits internal data model, the commands
             | that allow you to clean up pretty much any mess (reset &
             | reflog probably being the most prominent ones) start to
             | somewhat make sense. If you had previous exposure to
             | anything computer-science, it very likely won't take more
             | than a few hours until the puzzle pieces start to come
             | together.
             | 
             | And it's time well-spent in my opinion; git will probably
             | be one of the longer-lasting constants in software
             | development.
        
           | dec0dedab0de wrote:
           | I use the Pycharm/Jetbrains Git GUI. At this point I can't
           | imagine effectively handling merge conflicts any other way.
           | 
           | EDIT: Also, I really like being able to look at a diff of
           | every file before I commit, and easily choosing which files
           | to include in a commit. Too often I see people on the CLI
           | accidentally committing changes they didn't mean to, because
           | there is no easy way to check everything at the last minute.
        
             | tailspin2019 wrote:
             | Yes Jetbrains have totally nailed this. I have tended to
             | prefer the command line for git but the exceptionally
             | designed GUI support in Rider is fast changing that -
             | especially for rebasing.
        
             | tcoff91 wrote:
             | even if you use the git CLI you can still set up a
             | mergetool so that when you are resolving merge conflicts
             | you can use something like BeyondCompare or P4Merge to
             | handle the merge conflicts.
        
               | mixmastamyk wrote:
               | Meld
        
               | Hamuko wrote:
               | And every Xcode installation on macOS comes with
               | FileMerge.app.
        
             | fiddlerwoaroof wrote:
             | There's a really easy way to check the diff before
             | committing on the command-line:                   git
             | commit -v
             | 
             | Displays a diff at the bottom of the editor that pops up to
             | write a commit message.
        
             | Ashanmaril wrote:
             | The Jetbrains IDE git GUI is by far the best git GUI I've
             | used, I feel lost trying to use git without it.
             | 
             | There's a user request that's been sitting around for a
             | while to pull it out into a dedicated application, which I
             | could personally get behind since we have one project at
             | work that's pretty difficult to run outside of Eclipse
             | 
             | https://youtrack.jetbrains.com/issue/IDEA-152437
        
             | stevenhuang wrote:
             | What's wrong with 'git diff'?
             | 
             | Then there's 'git add -i' to easily choose which files to
             | add
        
           | gitgitgit wrote:
           | I use Git via the GitHub Desktop client
           | (https://desktop.github.com) and find it _very easy_ to use
           | Git without issue by following a simple rule: don't be
           | clever. I have branches, I commit, I squash merge via a Pull
           | Request. No rebasing, no moving commits around. There might
           | be workflows where rebasing etc. are important and certainly
           | in those cases, using a GUI is probably not a great idea --
           | but it's certainly possible to use a GUI without issue if you
           | keep your workflow simple.
        
             | phkahler wrote:
             | I squash locally, but learning to do that required learning
             | vim. Fortunately vimtutor. Then my distro changed the
             | default text editor launched from git... fortunately I knew
             | enough to get by with that one - which might be emacs but I
             | haven't verified.
             | 
             | Git is really weird but useful.
        
               | gbear0 wrote:
               | The default editor is usually configurable (of course
               | you'd have to learn all the different contexts you can do
               | this from first to know this is a thing ...
               | discoverability is hard).
               | 
               | For example in ubuntu you can do                 sudo
               | update-alternatives --config editor
               | 
               | Some programs will use the environment variable $EDITOR,
               | so you can add this to your shell startup configs
               | export EDITOR=vi
               | 
               | Or specifically for git cli you can run
               | git config --global core.editor vi
        
               | sethd wrote:
               | Git will use whatever editor you have defined in $EDITOR.
               | You can also define this specifically for Git via global
               | config (~/.gitconfig) if you don't want it to use your
               | session's $EDITOR variable:                   [core]
               | editor = vim
        
           | overgard wrote:
           | I find GUI's to be very helpful; most of my commits happen
           | through VSCode's commit panel. For my home Unity3D project I
           | use sourcetree because my commits unfortunately end up being
           | to a lot of unrelated files (blame unity), and having a UI to
           | stage them saves a lot of typing. I avoid anything like
           | rebasing (never got the point of that), but I use branches
           | liberally. I find with this setup, I only need to use a
           | handful of command line options, and I haven't screwed up a
           | local repository in a long time.
        
             | muststopmyths wrote:
             | If you are on Windows, Visual Studio's GUI is actually
             | quite good for staging, merging and diffing. I tend to use
             | it for most of those simpler kinds of things while still
             | doing commits, rebase etc. from the command line.
             | 
             | Same for VSCode on non-Windows.
             | 
             | I only mention this because I came to hate Sourcetree in
             | its newer iterations on Windows so much that I tried out
             | Visual Studio's support and was pleasantly surprised.
        
           | zubspace wrote:
           | I'm a huge fan of git fork [1] on windows (or mac). Looks
           | good, never failed me and does everything I need (branching,
           | rebasing, merging, squashing, cherry picking, blaming and it
           | can even show lost commits with reflog). And it performs
           | really well (in contrary to sourcetree).
           | 
           | [1] https://git-fork.com/
        
           | smilekzs wrote:
           | I disagree.
           | 
           | First of all, a well-designed Git GUI (examples below)
           | exposes the git's underlying data model to you; in contrast,
           | the CLI obscures it until something breaks and you're forced
           | into it without context. Git operates on a graph and there is
           | simply no way around it. The more you're exposed to the
           | graph, the better you can mentally model it and ask it to do
           | the right things.
           | 
           | While there are many half-baked Electron-based UIs that only
           | unnecessarily complicates things, there are good ones too:
           | 
           | On Windows (and Linux thru Mono), I use GitExtensions. The
           | visualizations are sane and discover-friendly. It will tell
           | you what to expect.
           | 
           | When I work on C++ projects, the one built into CLion
           | (JetBrains family; as mentioned by a sibling comment) is very
           | good on its own. What impresses me the most is that has good
           | visual support of a patch-oriented workflow. You can work
           | with multiple "changelists" offline, shuffle individual
           | changes around, seamlessly convert between changelists and
           | patch files, and (most importantly) still work nice with the
           | vanilla git model as the "actual history". It also works
           | transparently with conceptually monorepo projects that have
           | multiple physical repos, allowing you to do simultaneous
           | commits.
           | 
           | I feel VSCode, GitHub client, Kraken, and several other
           | Electron-based stuff, are too focused on the "polish" than
           | substance, or are too opinionated to be used across repos I
           | don't own.
        
             | jonnycomputer wrote:
             | So back when I was learning git, I was very shy about using
             | any GUI because I was afraid that it would make learning
             | how git works that much harder. I think that I somehow felt
             | that the CLI was more fundamental, in some way. But I think
             | you are right, and I was wrong. A better interface that
             | puts the graph front and center would have led me to learn
             | it so much faster, especially when it also exposes the
             | command line equivalents, as magit does (or so I've heard).
        
             | [deleted]
        
             | cerved wrote:
             | The CLI doesn't obscure as much as presupposes that you
             | understand internal workings of git.
             | 
             | All GUIs are not created equal. The JetBRains GUIs are
             | pretty good. Others try and impose git "their way" and just
             | invite creating a mess.
        
           | swader999 wrote:
           | I agree and limit Git Gui usage to read-only use, any mods to
           | git I use command line.
        
             | yxhuvud wrote:
             | Git Gui is a decent tool to compose commits, but for
             | everything else I can't see myself using anything but the
             | command line.
        
               | rjmunro wrote:
               | gitk (and similar) are great for browsing the history and
               | figuring out what is going on. I couldn't live without
               | it.
        
               | tcoff91 wrote:
               | I do virtually everything with Magit. It's the best of
               | both worlds IMO. You still need to actually understand
               | git and its commands but it's like using the CLI with far
               | fewer keystrokes and a better log interface than the CLI.
        
           | PufPufPuf wrote:
           | Funnily, I use a GUI almost exclusively to resolve mess-ups:
           | Ungit is a great tool to understand the current state of the
           | repository and fix it.
        
           | an_opabinia wrote:
           | Not a single person I've met using git in the last decade has
           | thrived using a UI for it.
        
             | lanstin wrote:
             | magit (for emacs) is quite good. But I still only use it
             | for browsing around mostly, or single-file commits. For
             | serious work, I start with git status, and then git diff
             | all the changes, and then group them and then commit then
             | in groups, then pull --rebase then push
             | HEAD:good_branch_name (by the time I've done all the above,
             | I have a better chance at a good name than I do for the
             | first commit). Then over to PR land, where we have "ff if
             | possible and delete source branch."
        
             | animal_spirits wrote:
             | I've said this in other threads but I'll proselytize here
             | as well. I really started to grok git after using the
             | lazygit terminal UI. I think it's really handy to see what
             | the current "state" of git is in and how to browse it
             | easily. Would continue to recommend.
             | 
             | https://github.com/jesseduffield/lazygit
        
             | oblio wrote:
             | That's a failing of Git. TortoiseSVN brought source control
             | to millions of people. A good tool should be fully
             | embeddable in a UI, 15 years after its launch.
        
               | OJFord wrote:
               | Or a success of git? No good GUI exists because they
               | realise they'd just be recreating things that exist, but
               | with a GUI frame?
               | 
               | If you wrote git 2.whatever from scratch would you
               | structure rhe commands a bit differently? Yeah, sure,
               | probably; but I always think these threads are way
               | overblown. The common stuff that you use frequently..
               | well you use it frequently, so either you remember it as
               | a result or you use the alias feature so that you can.
               | For the less common stuff.. if you have to look it up in
               | the excellent documentation, is that a failing?
        
               | [deleted]
        
               | approxim8ion wrote:
               | We still use tortoiseSVN at work. It's crude but
               | shockingly simple to use. Moving to git would be a
               | significant expense just to train people not to break
               | things and to get them used to CLI.
        
               | somethingor wrote:
               | TortoiseGit exists too and is fantastic IMO:
               | https://tortoisegit.org/
        
             | dragonwriter wrote:
             | > Not a single person I've met using git in the last decade
             | has thrived using a UI for it.
             | 
             | I do most of my git through one or another UI (right now,
             | mainly the integrated functionality in VSCode, a gitflow
             | workflow extension for VSCode, and repository history graph
             | extension for VSCode that supports doing operations against
             | branches/tags/commits from the graph.) I feel loke I'm
             | thriving that way.
             | 
             | Its not a substitute for knowing git, though, and I think
             | that people who lean on a UI as a substitute for knowing
             | what is going on underneath rather than as a convenience
             | layer are not likely to thrive.
        
             | [deleted]
        
         | MayeulC wrote:
         | > What does "git reflog" or "git reset --hard ...." do? What
         | are the implications?
         | 
         | This is supposed to be covered in `man git reflog` and `man git
         | reset --hard`. I admit that it could be more readable though.
         | Currently, it's more of a technically-correct introduction than
         | a layman's. I guess it's really more of a documentation for
         | experts. Some have made fun of this: https://git-man-page-
         | generator.lokaltog.net/
         | 
         | In layman's terms, `git reflog` is the history of the positions
         | you were at: you'll see every commit you've visited recently,
         | so as long as something was committed, you won't lose it. It's
         | here in case you lose some commit identifier (for instance you
         | finished rebasing but are not happy with the result: the branch
         | now points to the sad commit. Grab the reflog, copy the commit
         | identifier and reset the branch to point it to where it was
         | before).
         | 
         | And `git reset --hard`... `git reset` changes the branch "tip"
         | (pointer) to another commit: the commit tree always exists.
         | Branches are "named commits". `git reset` moves these tags
         | around. The `--hard` part "just" replaces the entire content of
         | your working directory (including non-committed changes) to the
         | commit you give as a parameter. With no parameters, it just
         | resets to the latest commit in that branch, so it's like saying
         | "clean my working directory back to what was committed, discard
         | my changes". Perfect for losing work.
         | 
         | I agree that git "porcelain" commands are sometimes ill-named
         | and a bit counter-intuitive to grasp. For me, learning git paid
         | of (sort of: I don't spend time fighting my issues, I spend it
         | helping others fix theirs).
         | 
         | I'm keeping an eye on better-designed alternatives like pijul.
         | mercurial is interesting and has better-named command, but I
         | sunk some time learning git already, and know it better, so hg
         | has very little more to offer to me.
        
         | Hamuko wrote:
         | > _The truth is, while we use git every day, most people really
         | don 't understand how it works._
         | 
         | Most people don't know how the Internet works and yet it's
         | widely used.
         | 
         | You don't need to understand the inner workings of git. You
         | just need to know some commands and some basic concepts.
        
           | agucova wrote:
           | The problem is not knowing git internal can very easily
           | backfire by deleting data, rewriting history, etc
        
           | matheusmoreira wrote:
           | > Most people don't know how the Internet works and yet it's
           | widely used.
           | 
           | Yeah. I've met many developers who have no idea what a cookie
           | even is, people who have never read a single IETF RFC.
        
             | uvesten wrote:
             | Me too, far too often. Those developers are most often
             | negative contributors...
        
         | ycken wrote:
         | > The truth is, while we use git every day, most people really
         | don't understand how it works.
         | 
         | It is a tool. One should not need to understand the inner
         | workings of a tool to use it. How many APIs do we use where
         | knowing how it does what it does is required? Whether it's
         | Stripe or Node or Bundler or ..., the user does not have to
         | know what happens inside. The need for incantations makes some
         | people feel powerful or exclusive. I just want my tools to do
         | their job so I can focus on doing mine.
        
         | lugged wrote:
         | I come across this attitude a lot.
         | 
         | Usually my response is if you use something daily, and you know
         | you lack the skills to use it effectively, why don't you
         | improve your knowledge and seek out training or education?
         | 
         | Do you treat a new programming language or framework with the
         | same disdain?
         | 
         | I know I'm gonna get some hate for pointing this out but this
         | same disdain is what causes things like the branchless
         | workflow. A workflow that hamstrings yourself to git stash as a
         | poor man's branch. I get it, I used that as crutch for years,
         | then I spent some time learning git properly.
         | 
         | Most people haven't even watched the one hour talk where Linus
         | talks about the design and building of git.
         | 
         | One hour might sound like a lot to understand why branching is
         | so amazing, and why distributed source control is hard but it's
         | a tool I've used for almost a decade and won't stop using for
         | the next decade. I think it was worth it.
        
           | Ensorceled wrote:
           | At one time I was an expert in 'C'. I was the goto guy at our
           | company for porting and performance issues and was often just
           | handed the entire project if it involved porting.
           | 
           | I have no memory of any of that beyond the basics now. Git is
           | like that. There is no way I will remember commands I only
           | use once a quarter or so when something goes wrong.
        
             | lugged wrote:
             | I don't know what to tell you, commit more code? Branch
             | more? Work in teams?
             | 
             | Maybe git isn't the right tool for you?
             | 
             | I have a set of commands I use multiple times a day, for
             | everything else there are manuals and docs to reference.
             | 
             | Git branch, commit, rebase, merge, clone, check out, pull,
             | push, submodule, remote, and maybe a couple more, are there
             | specific commands you don't use daily? Other than remote
             | and submodule I use all of those almost daily.
        
               | megameter wrote:
               | That's nice, but most of us here are version control
               | consumers, not version control professionals. We need
               | something that has very few knobs to turn because our job
               | is focused around delivering value through other tasks.
               | 
               | Git is highly professionalized. It has layers of modal
               | state. That is built into the operating model. It is made
               | for Linus Torvalds, a professional merger of code. If you
               | are using all of those commands "almost daily", you are a
               | professional code-merger too.
        
               | Ensorceled wrote:
               | I was replying to this part of your comment:
               | 
               | > Usually my response is if you use something daily, and
               | you know you lack the skills to use it effectively, why
               | don't you improve your knowledge and seek out training or
               | education?
               | 
               | Seeking out that training would be useless since I don't
               | use git enough.
               | 
               | > Maybe git isn't the right tool for you?
               | 
               | Git is definitely the tool for me. It's better than any
               | other available tool for my situation.
               | 
               | Why the hell would I branch more? Just to get better at
               | git? Sorry, I'm sorry that I work on a small team! Maybe
               | I should go back to CVS?
               | 
               | Stop gate keeping.
        
             | eric4smith wrote:
             | Bingo.
        
           | arxanas wrote:
           | > I know I'm gonna get some hate for pointing this out but
           | this same disdain is what causes things like the branchless
           | workflow. A workflow that hamstrings yourself to git stash as
           | a poor man's branch.
           | 
           | FYI, the branchless workflow linked to in the post is really
           | the opposite of this. It encourages making commits even more
           | often than you would in the traditional branching workflow,
           | and discourages using the staging area or stashes when
           | commits would work fine.
        
       | MehdiHK wrote:
       | Git Tower GUI app has undo feature too, which is very handy. They
       | announced it in this post: https://www.git-tower.com/blog/how-we-
       | built-undo/
        
       | voiper1 wrote:
       | Reference to a helpful wizard for fixing your git mistake:
       | http://sethrobertson.github.io/GitFixUm/fixup.html
        
         | Egoist wrote:
         | Wow, probably one of the best guides i have seen for git. Wish
         | i knew this existed when i was a beginner
        
       | thewebcount wrote:
       | I'm sorry, but how many bits of git's UI do we have to force
       | users to manually replace before we realize that the entire
       | problem is git's UI?
       | 
       | Between the tone deaf responses here about "using a GUI client is
       | the problem," to the tone deaf responses of "you just have to
       | learn it's internal architecture," it should be obvious what the
       | problem is. The problem is not just being able to undo a mistake
       | (though that's certainly _one_ of the problems). Git is an
       | incredibly user-hostile experience, and someone needs to fix or
       | replace it. Can we just say it out loud and stop pretending that
       | the problem is the literally thousands of users who have problems
       | using it?
        
         | TobTobXX wrote:
         | Admittedly I did spend like a combined hour troubleshooting git
         | over the last two months.
         | 
         | But git saved me an immeasurable amount of hours in return. I
         | was asked what I worked on some specific week back in may --
         | git saved me. I had to look up what performance my program had
         | before a specific change -- git saved me. I had to try stuff
         | out without messing up my codebase -- git saved me.
         | 
         | True, I invested quite a few hours and I still do, but I think
         | the investment pays itself off. I'll never ever do a project
         | without git.
        
         | gumby wrote:
         | > tone deaf responses of "you just have to learn it's internal
         | architecture,"
         | 
         | Why is this tone deaf? It's a development tool for
         | _programmers_ and the internal structure is conceptionally
         | pretty straightforward. Understanding your tools is pretty much
         | prerequisite. You don't have to have written a compiler to use
         | one, but you do have to have a model of what it does. Git is no
         | different.
        
         | rjmunro wrote:
         | There is no doubt that a bunch of the general commands are
         | really poorly named, or mixed together. `git checkout branch`
         | means switch to a branch - that's fine. But `git checkout
         | filename` means "undo changes to the file". What? That's
         | totally insane.
         | 
         | `git branch new-branch-name` means create a new branch. Great,
         | but it doesn't check out the branch, which you want like 99.9%
         | of the time. If you want to do that, you use `git checkout -b
         | new-branch-name`. Yes, a third separate use for git checkout.
         | 
         | Why not (e.g.) `git branch -c new-branch-name` with a config
         | option to make `-c` the default if you want it?
         | 
         | If you rebase and push, it tells you to do a `git pull` to
         | "fix" it, when in every workflow I've ever done, you want to
         | add a `-f` and push away, just be aware that you are
         | intentionally overwriting the remote branch.
        
           | ufo wrote:
           | By the way, I recommend using `push --force-with-lease
           | `instead of `push --force`. This way it doesn't destroy the
           | remote changes if someone else pushed while you weren't
           | looking.
        
           | RvdV wrote:
           | New commands 'git switch' (git switch -c for new branch) and
           | ' git restore' address exactly that issue and are available
           | on newer git versions, so it's being worked on!
           | 
           | I do agree with the second example. Pulling and merging with
           | remote after a rebase makes a terrible mess!
        
           | npteljes wrote:
           | And if I create a new branch locally, why must I specify what
           | name I'd use for it on the remote? Why would I like an
           | _other_ name I wonder? It 's fantastic that it can do this,
           | but the default should be the branch name I'm using and
           | that's that.
        
           | mdaniel wrote:
           | > But `git checkout filename` means "undo changes to the
           | file". What? That's totally insane.
           | 
           | Heh, and I'll do you one better: it's _unstaged_ changes, so
           | it won 't put the file back to the HEAD version 100% of the
           | time >:-)
        
           | cerved wrote:
           | Git checkout branch means change the entire working tree to
           | the reflect the state of the branch and git checkout file,
           | checkout the state of that file in HEAD. Both commands to the
           | same thing, change the state of your working tree to reflect
           | a point checked into version control.
           | 
           | It sounds like you are unaware of                 git switch
           | branch
           | 
           | and                 git switch -c new-branch
        
             | Vinnl wrote:
             | Just a tip: when teaching people, the readable alias is
             | easier to remember and understand, i.e.
             | git switch --create new-branch
        
               | riquito wrote:
               | It was a good example: it was obvious by the name of the
               | branch and he/she was teaching the real word use case
        
         | lawn wrote:
         | This is the one thing I took with me from The Design of
         | Everyday Things: usability design matters, and it matters a
         | lot.
        
         | sloucher wrote:
         | Last time I checked, 5 of the top 10 questions on StackOverflow
         | were about Git...
        
           | adamrezich wrote:
           | still true! but that isn't a great metric necessarily, as #10
           | is "What is the "-->" operator in C/C++?"
           | https://stackoverflow.com/questions/1642028/what-is-the-
           | oper... which is just a novelty rather than a common question
        
           | greenshackle2 wrote:
           | Maybe because like 90% of devs use git; there's no language
           | or framework that is used by so many.
        
         | [deleted]
        
         | nexuist wrote:
         | The problem is just that collaborative text editing between
         | multiple users simultaneously is hard. It's a human problem and
         | git attempts to be a technical solution but the abstraction
         | fails at the edge cases.
         | 
         | Regardless, what's so bad about deleting the repo and pulling
         | from remote if you can't figure out why you hosed it? It's not
         | like it costs you anything to do `rm ... && git clone ...`. And
         | it's not like this happens daily either.
         | 
         | In the rare case that someone hoses remote, yes you'll have to
         | do some weird git-fu to get everyone working again, but it's
         | really hard to hose remote if you stick to the pull -> commit
         | -> push -> merge pattern, which is what 99% of users are doing
         | anyways. I've used git for 9 years and I've never had to spend
         | longer than an hour troubleshooting git based BS. And if you'll
         | remember, 9 years ago git wasn't the clear winner, it had
         | competition via SVN and Mercurial. Both of them are practically
         | irrelevant at this point so however bad git's UI was, it's
         | clearly better than anything else that existed before.
        
           | vxNsr wrote:
           | GitHub is what made git so popular, git wasn't inevitable,
           | and GitHub didn't become huge because of git, GitHub's big
           | innovation was attaching a social network to a software/code
           | repo. It's what made it way more popular than basically all
           | the competition, which were just software/code repos but
           | didn't have a great network/social story. (Also at the time
           | GitHub was coming out, the biggest player in the space
           | decided to monetize in an annoying way.)
        
           | chriswarbo wrote:
           | > It's a human problem
           | 
           | If it were a human problem, how could alternatives like
           | Mercurial and Darcs get consistent amounts of praise for
           | their intuitive workflows?
           | 
           | > 9 years ago git wasn't the clear winner, it had competition
           | via SVN and Mercurial. Both of them are practically
           | irrelevant at this point so however bad git's UI was, it's
           | clearly better than anything else that existed before.
           | 
           | SVN isn't distributed; it mostly tried to replace CVS, which
           | it managed to do very successfully.
           | 
           | As for DVCS, the fact that system X became more popular than
           | system Y doesn't mean that _every_ aspect of X is better than
           | Y. Many would say git succeeded _despite_ its awful
           | interface. As far as I can tell, the main feature of git was
           | its speed; that made it usable for huge projects like Linux
           | and Xorg, and this endorsement from high-profile projects
           | gave git the edge for DVCS hosting sites like Gitorious. Then
           | GitHub came along, and grew into such a behemoth that git
           | became the de facto standard.
           | 
           | See also: WorseIsBetter
        
             | umvi wrote:
             | > If it were a human problem, how could alternatives like
             | Mercurial and Darcs get consistent amounts of praise for
             | their intuitive workflows?
             | 
             | Because maybe mercurial's real problems wouldn't show up
             | until people started using it at scale.
             | 
             | This is a classic problem that happens time and again.
             | 
             | Windows vs. Mac back in 2005:
             | 
             | "Windows having malware is a human problem"
             | 
             | "If it were a human problem, how could alternatives like
             | Mac get consistent amounts of praise for their lack of
             | malware?"
             | 
             | Turns out it's just because Mac didn't have a big enough
             | market share. As soon as it did, Apple could no longer
             | claim that Macs can't get malware because they can and do.
             | 
             | Similarly, if you scaled up the number of Mercurial users
             | by several orders of magnitude so that it was now
             | "mainstream", I'm sure some of its lesser known pain points
             | and/or counter intuitive behaviors would start floating up
             | to the top 10 HN stories. But since hardly anyone uses
             | Mercurial vs. Git, that doesn't happen. Just because a
             | minority of users praise something (<insert lesser known
             | language>, <insert lesser known DB>, <insert lesser known
             | VCS>, etc.) doesn't mean if you scaled up the userbase one
             | or more magnitudes it would continue getting that level of
             | praise from all users.
        
               | Izkata wrote:
               | > Because maybe mercurial's real problems wouldn't show
               | up until people started using it at scale.
               | 
               | I actually tried both git and mercurial almost a decade
               | ago having had only experience with subversion, and found
               | git to be much easier to understand and use. I don't
               | recall what those pain points were, and am sure I
               | couldn't describe them correctly if I did remember, but
               | because of that I do expect such things to start popping
               | up if more people used it.
        
           | daxelrod wrote:
           | I agree that collaborative text editing between multiple
           | users simultaneously is hard.
           | 
           | That doesn't mean that Git couldn't have a much better UI for
           | this problem than it does. And while I agree that Git seems
           | to have mostly won over SVN and Hg, it doesn't follow that
           | it's because of its UI. (For example, I think that a lot of
           | Git's success actually comes from the UI of GitHub, not Git
           | itself, but I don't have evidence to back it up.)
           | 
           | Take a look at the Research section at the bottom of
           | https://gitless.com/ for work that's been done on how to
           | accomplish the same operations with a simpler conceptual
           | model.
        
             | lanstin wrote:
             | This is the real interesting problem. Even simple subtle
             | decisions like "should this list be kept sorted, or have
             | new things added to the end" determine under what
             | conditions you will hit a new conflict and when you won't.
             | List of enums, add to the end, and if 2 branches grab the
             | next enum value then you'll see a conflict. List of lets
             | say URL prefixes keep in order, then most randomly added
             | URL prefixes will not collide or conflict, only conflicting
             | if you get 2 things trying to operate on the same prefix.
        
             | FractalHQ wrote:
             | Wow. Reading the home page of gitless made me both excited
             | to use it and angry at how poorly designed git's UI and UX
             | are. Thanks for sharing this!
        
         | quickthrower2 wrote:
         | I feel that I only understand git because I'm forced to use it
         | for years, but the experience could have been a lot less
         | painful. I use a GUI for sure. Do people really diff and
         | resolve big conflicts at a command line? I never figured out
         | how.
        
           | cerved wrote:
           | git mergetool
           | 
           | or                 git checkout --ours/theirs && git add .
        
           | rjmunro wrote:
           | Just delete the bits you don't want and `git add`
           | 
           | It helps a lot to set:
           | 
           | git config --global merge.conflictstyle diff3
           | 
           | then you can see the before as well as the 2 changes you are
           | trying to resolve.
        
       | renewiltord wrote:
       | It is interesting. I've never had any trouble with git. I think
       | the reason is that I learned it relatively early in my career and
       | so I had the luxury of "What's the right way to resolve this
       | situation?". I have never lost data despite using filter-branch,
       | rebase, bad merges, bad rebases, bad branch deletes...
       | 
       | Still, the UX sugar of undo sounds quite nice. I only worry about
       | introducing something heavyweight into the thing. If I use
       | branchless will it force others to use branchless too?
        
         | arxanas wrote:
         | No, it doesn't force others to use branchless at all. The git
         | undo data is stored in a separate database in your .git
         | directory, so other people won't have access to it. (Of course,
         | this means that they can't use git undo on your actions.)
        
       | amelius wrote:
       | Would this work on a pull from a remote?
       | 
       | Or how about after pushing to a remote?
        
         | arxanas wrote:
         | Pull from a remote: yes, it will rewind the local references to
         | their old positions.
         | 
         | Push: sadly, no.
        
       | phonebucket wrote:
       | git config --global alias.undo 'reset --soft HEAD~1'
       | 
       | Not that I would include this in my own shell. To the authors two
       | example uses: 1) Undoing an amended commit. But if you're
       | comfortable amending a commit, can't you just amend your amended
       | commit? 2) Accidentally commiting an incorrectly resolved merge
       | conflict. Revert the change if you want to be non-destructive.
       | Reset HEAD~1 otherwise.
        
         | renewiltord wrote:
         | 1. I believe it's not that you want to amend it, but that you
         | want to restore its pre-amended state. I would use the reflog
         | to look that up and then reset to it but this makes that easy
         | and hence, more accessible (which is good)
         | 
         | 2. Yeah, but I think the UX improvement of a single command to
         | say "Go back to where I was" is reasonable.
        
       | optymizer wrote:
       | This is an excellent idea and I'm glad it's making its way into
       | the open source community.
       | 
       | My company has an equivalent to 'git undo' that basically undoes
       | anything you just did to your local repo.
       | 
       | It's just so freeing. Sometimes you need that Ctrl+Z so you can
       | undo and redo things correctly. It gets your mind back to
       | whatever you were doing before without needing to debug wtf just
       | happened.
        
       | zach_garwood wrote:
       | This seems like putting a training wheel on a training wheel. git
       | is already the easiest to understand of any VCS that I've used,
       | and it's somewhat hard to do something in git that can't be
       | reversed. As the articles states, it's unlikely you'll ever lose
       | your changes. Further, this doesn't seem to be that different of
       | a concept from git reset, so why not learn reset instead of yet
       | another command?
        
         | sedatk wrote:
         | > git is already the easiest to understand
         | 
         | You mean Mercurial :)
        
           | zach_garwood wrote:
           | I concede the point :)
        
         | jcranmer wrote:
         | > git is already the easiest to understand of any VCS that I've
         | used
         | 
         |  _Breaks down in uproarious laughter._
         | 
         | One of the worst offenses git is its use of multiple different
         | jargon terms for the same concept; indeed, it's the only VCS
         | I've used where reading help leaves me _less_ sure than when I
         | started if it does what I want it to do.
         | 
         | If I accidentally leave my system in a weird state (say, I'm in
         | the middle of a git rebase and I forgot to git rebase
         | --continue), and I start doing some regular git commits, the
         | resulting mistakes are, while possible to recover from,
         | difficult to do so unless you know git's internals. I have to
         | use the "what's that git command to list the commits I just
         | dropped on the floor by accident?" with surprising frequency.
        
           | zach_garwood wrote:
           | What are the jargon words youre referring to? In my
           | experience, it uses the same jargon as the other VCSs.
           | 
           | Perhaps you have a different workflow than me, but I don't
           | find myself rebasing all that often to begin with. I
           | generally don't rewrite history unless I truly fucked up. And
           | since I'm in "I fucked up" mode, I take extra care with
           | commands I type.
           | 
           | I don't wanna be like Apple and say "You're holding the phone
           | wrong," but maybe you shouldn't be doing frivolous rebasing.
        
             | jcranmer wrote:
             | The staging area (aka "index" aka good god don't try to
             | read git glossary's index for this) is a bad one. There's
             | definitely several cases where I've read the documentation
             | and struggle to figure out if it will or will not affect
             | the working checkout or not.
        
         | simias wrote:
         | Hard disagree, git's docs and UI have improved over the years
         | but every time I have to teach it to a beginner I realize how
         | arcane and scary it is, especially when compared to old school
         | centralized VCSs like subversion.
         | 
         | Not that I'd trade git for subversion mind you, in the hands of
         | a trained individual git is a godsend, but the training part
         | can be arduous.
         | 
         | Even among DVCSs I'd argue that mercurial for instance is
         | vastly easier to pick up.
        
           | zach_garwood wrote:
           | If it's an issue of having to read the docs or the man, well
           | I've been at work like this for a little over a decade and I
           | still have to pull up a reference when I want to do something
           | nontrivial in, not only git, but pretty much every cli tool I
           | use on a regular basis. Cli tools, frameworks, libraries,
           | languages... I have to pull up a reference for everything I
           | do as a programmer, so it's hard for me to muster up the
           | indignity for having to look up how git works.
           | 
           | If it's a matter of understanding the flow of the tool, then
           | I will have to concede that mercurial probably is easier to
           | understand for the beginner.
        
             | rileymat2 wrote:
             | `git add <file>`
             | 
             | Wait, how do I remove it from staging? It seems there
             | should be some symmetric operation, `git remove <file>` or
             | something. Maybe git rm `<file>`, whoa don't do that.
             | 
             | No, it is `git reset HEAD -- <file>`. There is no mental
             | symmetry.
             | 
             | Or why use add at all? What am I adding it to? It is so
             | generic, why not `git stage file` and `git unstage file`?
             | 
             | I agree that you need to read and learn tools, but there is
             | a lack of consistency and symmetry in many of the commands
             | which make it harder.
        
         | arxanas wrote:
         | Git reset doesn't e.g. reset the positions of multiple branches
         | to their historical positions. In fact, some of that data can
         | be lost forever to Git (branch deletions are not tracked
         | anywhere).
        
       | quickthrower2 wrote:
       | Nice, I can evolve from https://xkcd.com/1597/
        
       | float4 wrote:
       | > novice users are terrified of it. When they make a mistake,
       | many would rather delete and re-clone the repository than try to
       | fix it
       | 
       | In my experience most beginners use a GUI like Atlassian
       | Sourcetree or the Github desktop client. It's a lot harder to
       | make mistakes using the GUI in my experience.
       | 
       | I still really like this idea though; eventually a subset of the
       | beginners wants to learn the git cli and that sure seems scary at
       | first.
        
         | Osiris wrote:
         | For JetBrains users, there is a built-in Git GUI as well.
         | 
         | It's not as easy to use as SourceTree, but since there's no
         | SourceTree for Linux, it works well enough.
        
         | jahnu wrote:
         | Can I give a shout out to Fork here for being another great GUI
         | for git. I'm not affiliated with them in any way. Just a happy
         | customer.
         | 
         | https://git-fork.com/
        
           | dewey wrote:
           | Agreed, another happy Fork user here. I switched from Tower
           | as it just got more and more expensive and added features I
           | don't need.
        
         | contriban wrote:
         | I occasionally screwed it up even with a GUI, possibly because
         | I was trying to recover something and then got lost. Once I had
         | to abandon the master branch for a year because I didn't know
         | how to fix it.
         | 
         | A year later I had probably learned how to force push correctly
         | and took hold of it again.
         | 
         | However I do think the GUI is great for git and that's why I
         | use GitHub Desktop. It's super simple. Most other GUIs try to
         | wrap git concepts too closely for comfort.
        
         | lukeinator42 wrote:
         | I really love the Jetbrains GUI built into their IDEs for this.
        
         | arxanas wrote:
         | GUI tools are a great step forward in my opinion, not because
         | the GUIs are necessary, but because the Git command-line
         | interface is really terrible.
         | 
         | I would like to see a GUI adopt these concepts. There's no
         | reason why we should limit the commit graph display to only the
         | current time, when we have enough information to scroll through
         | its past states as well.
        
       | Vaslo wrote:
       | I used GIT recently for tracking an SSIS package and despite many
       | commits I still have no idea whether I should use a rebase or a
       | reset or a hard reset. Reading the manual does not help. I just
       | simply want to undo a mistake. Glad I am not the only one who
       | feels dumb about this.
        
       | noxer wrote:
       | obligatory mention of fossil-scm.org just in case someone don't
       | know yet and would like a version control system++ that actually
       | works for/with you.
        
       | gerbilly wrote:
       | What makes git really complicated is that for every command you
       | type, there are two things that may be affected:
       | 
       | * the working copy
       | 
       | * the graph
       | 
       | And it gets better, if any file gets disconnected from the graph,
       | it can be hard to locate. (Yes I know, it can be found in the
       | reflog)
        
         | rags2riches wrote:
         | Let's not forget about the index. Or is it called the staging
         | area?
        
           | RichardCA wrote:
           | This conceptual overloading of language can be traced back to
           | Linus' first commit.
           | 
           | https://github.com/git/git/commit/e83c5163316f89bfbde7d9ab23.
           | ..
           | 
           | The original idea was "current directory cache" and that
           | still pops up in the syntax.
           | 
           | I always run "git diff --cached" as a last sanity check
           | before a commit.
        
       | OhNoMyqueen wrote:
       | The most painful mistakes beginers endure with git are
       | irrevocable code removal from the current working directory
       | because of bad usage of `git clean`, `git reset` (or `git merge`
       | if you're brutish enough). This problem cannot be solved by using
       | git, because git doesn't have any reference to such code.
        
         | juped wrote:
         | Also from deleting their whole checkout.
        
         | Leherenn wrote:
         | A bit less painful, in the sense that you probably won't lose
         | work, but still quite a headscratcher is line endings issues.
         | Not amount of `git checkout .` or `git reset --hard` will help,
         | and you just have massive diffs with no obvious change. I
         | recloned the repo quite a few times in my younger days over
         | this, and I still have to think deeply to be sure to use the
         | correct configuration.
        
         | nsomaru wrote:
         | Am I doing things wrong if I have never used these commands?
        
           | rjmunro wrote:
           | No, IMHO you are doing things right. I virtually never use
           | those commands, I've been using git for well over 10 years,
           | and have totally got used to all it's quirks.
        
           | jonahx wrote:
           | Probably not using git ideally. Do you clean your history
           | after working on a feature?
        
           | jdauriemma wrote:
           | Try not to think of it in terms of right and wrong. `git
           | clean` is useful, though not "can't-live-without-it" useful.
           | I couldn't imagine my workflow without `git reset`, though,
           | and I recommend checking it out!
        
         | anamexis wrote:
         | I agree, these are the only times I've irreversibly gotten
         | myself into trouble.
         | 
         | I think it would be possible to solve these with git, by doing
         | something like automatically running a `git stash --include-
         | untracked` before an operation that can clobber untracked
         | files.
        
         | kahkeng wrote:
         | I find it pretty useful to use the `--patch` or `-p` option
         | (also a mnemonic for "prompt") to various commands:
         | 
         | `git add -p`: prompt which hunks should be added to staging
         | 
         | `git checkout -p`: prompt which unstaged hunks should be thrown
         | away
         | 
         | `git checkout HEAD^ -p`: prompt which hunks from HEAD should be
         | discarded
         | 
         | `git reset -p`: prompt which currently-staged hunks should be
         | unstaged
         | 
         | `git reset HEAD^ -p`: prompt which hunks from the HEAD commit
         | should be unstaged
         | 
         | Nice thing is that you get interactive yes/no prompts with a
         | preview of the change for each hunk, and you can also quit
         | early if you realize it's not the command you want.
         | 
         | Doesn't fully address the potential for lost changes, but slows
         | it down by adding an interactive roadblock for each change.
        
           | secondcoming wrote:
           | hunk?
        
         | abdusco wrote:
         | If you're using JetBrains products, you can view the history of
         | the changes for the whole project and revert mistakes by right-
         | clicking the project > Show Local Changes.
         | 
         | https://twitter.com/abdusdev/status/1403050600925962247
        
         | rags2riches wrote:
         | Don't forget `git checkout`!
         | 
         | When I help people get started with git, I tell them several
         | times to commit as often as they can. If they committed it, I
         | can probably save them when they think they lost something.
        
       | alkonaut wrote:
       | I hate git passionately, but I still find it somewhat
       | understandable. I understand what it does but that of course
       | doesn't change my view that its UX has the elegance and
       | consistency of an early php draft that went through a document
       | shredder.
       | 
       | Git has a nice elegant layer underneath though. The DAG of
       | commits is a very nice model, covered in a layer of terrible
       | commands, and a few rather unnatural abstractions like the
       | staging area.
       | 
       | I think to effectively use it you need to work with your brain
       | squarely in that lower layer. Trying to think in terms of
       | sequences of commands rather than a tree of commits and
       | references is hopeless.
       | 
       | The fact that the UX concepts (commands, working copy, reflog
       | staging area, ...) and the underlying model (graph) are difficult
       | to reconcile is git's biggest weakness.
       | 
       | The difficulty with which is models some of the most common use
       | cases (centralized, often including a few large binary files) is
       | another.
        
         | yarg wrote:
         | There's a limitation to the DAG model that has bothered me for
         | a long time.
         | 
         | I don't always want a branch to descend from a commit -
         | sometimes I want it to descend from another (less featureful)
         | branch.
         | 
         | I want the ability to say that branch 1.1 is equivalent to
         | branch 1.0 + {some set of changes} is something that would be
         | exceptionally useful in a lot of circumstances.
         | 
         | (And I know this would create some new fun and games from a
         | conflicts perspective, but I think it'd be worth it for any use
         | case that involves long term maintenance of different releases
         | of the same piece of software.)
        
           | leafmeal wrote:
           | So like a branch that automatically rebases on another
           | branch? I think the issue with this is the inevitable
           | conflicts and race-conditions. While nice in theory, often
           | you need manual control to sort things out.
        
             | yarg wrote:
             | Not quite - branches get ancestors.
             | 
             | A new repository starts with an empty branch.
             | 
             | A DAG gets layered on top.
             | 
             | I mentioned conflicts, but can you explain where race
             | conditions would arise?
        
       | chuckdries wrote:
       | gitkraken also has an undo button
        
       | Simplicitas wrote:
       | This is an awesome idea. Can't wait to hear the objections from
       | the purists.
        
         | RichardCA wrote:
         | The purist will say: You are always free to write your own
         | porcelain.
        
         | idoubtit wrote:
         | I've watched the first case: amend a commit then undo. And I
         | believe it shows serious shortcomings :
         | 
         | - The interactive interface of `git undo` is probably too hard
         | for beginners. Designing simple interfaces is hard, and you
         | can't pplease everyone.
         | 
         | - It seems `git undo` simply does a `git reset--hard` toward a
         | designed commit. The user probably expected to return to the
         | state _before the last git action_. Instead `git undo` reverted
         | the amend, but also reset the index and remove the local
         | changes. At this point, the beginner could scream  "Undo lost
         | my changes! I just wanted a second commit instead of an amend."
         | 
         | Undoing could mean `git reset --hard {hash}`, but in many cases
         | `--hard` would have unwanted effect and the default `--mixed`
         | would be more suitable. But even in this case, it's not a full
         | undo, since the index is not preserved: you don't end up in the
         | same state as before the `commit --amend`.
        
           | spicybright wrote:
           | Why is it so hard to implement a git undo? You have a
           | previous state, and a current state. Just roll it back.
        
           | arxanas wrote:
           | There is a design to address undoing changes to the index:
           | https://github.com/arxanas/git-branchless/issues/10
           | 
           | It runs a `git checkout`, not a `git reset --hard`, so it
           | will stop you if there are incompatible changes. Of course,
           | if `git undo` can be made to lose your staged or unstaged
           | work, then that's a bug.
           | 
           | Fortunately, you can undo the result of any `git undo` with
           | another `git undo` that goes one more step back in time.
        
       | 29athrowaway wrote:
       | There is a large graveyard of "simple git tools", many of them
       | portray themselves as happy GUIs that prevent you from learning
       | git...
       | 
       | None of them works. At some point you will be told to fix the
       | problem by hand.
        
       | [deleted]
        
       | robin_m wrote:
       | Quick tips for people that find git confusing:
       | 
       | - Use a recent version of git. The error messages have improved a
       | lot, have been localized (unless you do `LANG=C git ...` to be
       | able to search it on internet), the UI has improved, `git status`
       | is more helpfull, ...
       | 
       | - Create an alias for `git log --graph --decorate --oneline
       | --all` or something fancier with `--format`. `--graph` should
       | help you a lot to visualise stuff. - Don't use `git reflog` but
       | `git log --graph --reflog`, it's much easier to visualize.
       | 
       | - Never use `git checkout`, but `git switch` and "git restore`
       | that were introduced in git 2.15 IIRC. They are much less
       | confusing and error prone.
       | 
       | - `--patches` (`-p` for short) can be used with `add`, `restore`,
       | `reset`, `log`. It helps a lot with commit hygiene.
       | 
       | - Most complex rebase are easier to do with `--interactive`
       | (`-i`).
       | 
       | - Activate `rerere` in your git config (it will reduce conflict
       | merges during rebases).
        
       | girishso wrote:
       | This seems like a very good idea. Only if we can scroll through
       | the commit hashes and see the preview of commit with help of fzf
       | or something similar, it will be totally awesome.
        
         | max_hammer wrote:
         | I use maggit and can scroll commit log using `ll`
         | 
         | You can also try `lazygit` it's a TUI written in Go
        
           | zhynn wrote:
           | I have been using lazygit for about six months, and I love
           | it.
        
         | arxanas wrote:
         | I would like to add fzf-style interfaces to checking out more
         | things. Hopefully, they could index both the commit message and
         | the commit contents when searching.
        
       | sombremesa wrote:
       | > Here's my theory: novice and intermediate users would
       | significantly improve their understanding and efficacy with Git
       | if they weren't afraid of making mistakes.
       | 
       | Here's something that happens when people are encouraged to make
       | more mistakes: they make more mistakes.
       | 
       | The piece where people are encouraged to _learn_ from these
       | mistakes is missing from the author 's equation. Without that,
       | this tool becomes a crutch at best, and a disaster waiting to
       | happen at worst.
       | 
       | Can we do better?
       | 
       | *Edit*: Let me answer my own question. We can do better - for
       | example - simply by adding the Git commands this program would
       | run, aside from the human readable explanation. Not sure what
       | people replying to this comment were aiming for, since they
       | clearly did not offer up a single suggestion.
       | 
       | Let me go a bit further and add that self-righteous soapboxes are
       | NOT a good thing, and as it stands none of the replies to this
       | comment were relevant. I was hoping to spark a discussion of what
       | else could be done to improve the experience, but I could have
       | worded my comment better.
       | 
       | On the other hand, you can do better.
        
         | yoz-y wrote:
         | I wouldn't be so harsh. I don't know a single program that was
         | made worse by adding undo. Imagine a painting program without
         | it. (I'm sure there are some artistic programs that do that but
         | those would be mostly toys)
         | 
         | Trying to learn from mistakes that can be solved by an undo on
         | local repository are mostly in the realm of "be more careful",
         | which is an impossible requirement to achieve in general.
        
           | shadowgovt wrote:
           | The cost of adding undo is usually the cost itself (i.e.
           | every operation the program can do must now be considered for
           | its reversibility). Not every program justifies that cost,
           | but I have also never seen a program that was made worse by
           | adding it.
        
         | petters wrote:
         | The tool prints what it is going to do in a nice format. That
         | is an opportunity for learning.
        
         | deeviant wrote:
         | If your suggestion for making software better is to make
         | mistakes so punishing that users are thusly properly
         | conditioned to not repeat the mistake then... may I never use
         | software you work on.
         | 
         | An analogy in my mind is a "hardcore"(where your in-game
         | character permanently dies if you die once) mode in a game. On
         | the surface, even it's name suggests that a really die hard
         | power gamer is going to want to try this mode, the phrase
         | beckons truly a true epic gamer experience that will test the
         | players skill to the utmost. But, you don't get that. You get
         | people getting level 2 by killing only level 1 critters for 10
         | hours straight (or equivalent), you get a boring, sterile, slow
         | progressing gameplay that is exactly opposite of what one might
         | imagine going into it.
        
           | Filligree wrote:
           | > An analogy in my mind is a "hardcore"(where your in-game
           | character permanently dies if you die once) mode in a game.
           | On the surface, even it's name suggests that a really die
           | hard power gamer is going to want to try this mode, the
           | phrase beckons truly a true epic gamer experience that will
           | test the players skill to the utmost. But, you don't get
           | that. You get people getting level 2 by killing only level 1
           | critters for 10 hours straight (or equivalent), you get a
           | boring, sterile, slow progressing gameplay that is exactly
           | opposite of what one might imagine going into it.
           | 
           | Well, yes and no.
           | 
           | Try combining it with a speedrun. You'll find you have to
           | take calculated risks, and this can indeed add another level
           | to the game.
        
             | deeviant wrote:
             | Yes, agreed.
             | 
             | I wasn't meaning to be dismissive of those that enjoy or
             | make use of these types of game modes, but really just
             | invoking how hardcore mode ends up on average with the
             | average user for analogy only.
        
         | burnished wrote:
         | Making a mistake is an opportunity to grow by testing and
         | validating your mental model of a system. If the price of a
         | mistake is too high that is the same as saying the price of
         | testing is too high. If you want to craft a world in which
         | people can learn more from fewer mistakes then I think that is
         | a laudable goal but here it sounds like you simply want to keep
         | that high cost. Side note; Factorio is a game where the price
         | of making a mistake in your build is having to pick a thing up
         | and try again. Very low friction for most mistakes. People
         | learn a lot in that game by making mistakes, myself included
         | (two direction trains leads you down a path of evil by the
         | way), and I think if you were to include friction into that
         | system to prevent them from wanting to make mistakes at all the
         | overall learning would go down.
         | 
         | Or for an entirely different example, are you also opposed to
         | FPGAs? Should people be forced to not simulate circuits before
         | sending them off to be fabricated, in the hopes that by making
         | the mistake more painful they won't make as many?
         | 
         | Besides its not like people need more examples in their lives
         | of situations where a mistake is not easily recoverable from.
         | 
         | So to answer your question; I certainly can't, I am a mistake
         | based learner. If you can do better then please, please, do.
        
         | handrous wrote:
         | Making it possible to "play" safely is maybe the best way to
         | help people learn.
        
         | onion2k wrote:
         | _Without that, this tool becomes a crutch at best, and a
         | disaster waiting to happen at worst._
         | 
         | The underlying assumption here is that undo features make
         | people bad at thinking. I suspect that might be true in a lot
         | of cases, but I think we should give users the benefit of the
         | doubt and start by believing that they're undoing something
         | that they tried to reason about and made a mistake with rather
         | than thinking they're just whacking in random commands hoping
         | to hit the right one. The outcome might be the same but one is
         | a little more kind.
         | 
         | However, a reasonable counter argument to that whole idea is
         | that without an escape hatch giving users a sense of safety
         | they'll never even _try_ to use any features that they perceive
         | as  'dangerous'. Not having the ability to roll back something
         | they've tried means they won't try, and that keeps _most_ git
         | users from becoming experts. An undo feature is an immensely
         | useful learning tool (so long as it always works as expected),
         | which is exactly what you want if you think that people should
         | be encouraged to learn.
        
         | _jal wrote:
         | Perhaps it should have been stated outright, but the operative
         | theory appears to be that if mistakes cost less, making more of
         | them _becomes_ the learning exercise.
        
           | [deleted]
        
       | saiojd wrote:
       | Great work. I wish usability/ergonomy was taken more seriously
       | for popular tools that everyone uses (like git). Another stupid
       | pain point with git is the inability to commit empty directories.
       | I mean, come on.
        
         | cerved wrote:
         | Git takes stability and extensibility seriously. Your demands
         | and expectations on version control may be radically different
         | from mine.
         | 
         | Empty directories do not contain files or information, it's
         | entirely reasonable for a VCS to omit such a feature. Not sure
         | which use case for git is hindered by the inability to check-in
         | empty directories. I would even suggest such a use-case may be
         | a case of DIW
        
           | rileymat2 wrote:
           | The use case it frustrates me in is when you want to work on
           | the structure of the repository before you have all the code.
           | 
           | For instance, it is nice to think about the repo holistically
           | sometimes before I have say an actual unit test to put in the
           | directory, it is nice to create that structure in the repo.
        
             | cerved wrote:
             | I see. But then why the record that structure in the index?
             | Isn't it enough to have it remain in the working directory?
             | Or if you need it in the index, just the canonical empty
             | .gitignore?
        
       | workethics wrote:
       | I feel like an outcast after reading all the comments here. I've
       | never really had issues using git. I didn't realize so many
       | people had trouble with it.
        
       | rexyg wrote:
       | I can't wait to start using this
        
       | caseydm wrote:
       | This is a great idea. There are well-documented ways to undo
       | things on stack overflow, but almost every way:
       | 
       | 1. Has three competing ways available to complete the 'undo'
       | 
       | 2. Every way has a scary caveat that the user must be aware of
       | 
       | It would be awesome to simplify the process for new users.
        
       | windowojji wrote:
       | `hg` literally already has `hg undo` as a command. It's good that
       | `git` can have a similar tool
        
       | gldnspud wrote:
       | While GitUp is a GUI app, and only available for macOS, I think
       | it's worth noting that it has some great undo/redo capabilities
       | built in.
       | 
       | From what I understand, some of them were more feasible to
       | develop because they implemented their own plumbing (GitUpKit),
       | instead of relying on the official git plumbing.
       | 
       | https://gitup.co/
        
         | dilap wrote:
         | GitUp is such a great app & fantastic UI design, but the author
         | gave up on it at maybe 80% of functionality, and I think for
         | that reason (among perhaps others), it never really caught on.
         | (It's open source and there are still occasional commits, but
         | it doesn't seem to be really actively worked.)
         | 
         | Nevertheless my main daily driver, along w/ the command line.
         | It's undo capabilities, best-in-class visualization of the
         | timeline, and ability to easily visually edit, reworder, and
         | squash commits remain amazing.
         | 
         | (I was disappointed to see newer git clients like Submlime
         | Merge did not take inspiration from GitUp.)
         | 
         | Ultimately I think the future of VC will be something patch-
         | based (pijul?) w/ a UI along the lines of GitUp.
        
           | jahnu wrote:
           | An ex-colleague of mine used to maintain a fork here. Maybe
           | you could encourage him to continue :)
           | 
           | https://github.com/douglashill/GitUp/releases
        
           | swisspol wrote:
           | Hey I didn't gave up on it at 80% functionality ;) It had
           | 100% for my needs and it's been rock stable since then - I
           | still use it daily!
           | 
           | But yes, I wasn't really worth _actively_ maintaining it as
           | it was feature complete and I didn 't intend to build a
           | business out of it.
        
             | dilap wrote:
             | Yes, I also use it daily, so thanks for making an amazing
             | tool!
             | 
             | 100% vs 80% is of course going to be subjective, but the
             | missing 20% in my opinion is built-in merging and a built-
             | in repo browser. When I've tried to advocate GitUp to my
             | coworkers, those are the two things that keep them going
             | back to SourceTree or Fork.
             | 
             | (Also, on our (admittedly, pretty large) repos, it's not
             | quite rock-solid; staging can be unusably slow (requiring
             | fallback to the command line), switching to the commit view
             | from the map view can be slow, and making lots of changes
             | to the working tree will crash GitUp.)
             | 
             | Still, a brilliant piece of software, and I am suprised
             | that (1) it didn't find a larger audience and (2) that it
             | wasn't more influential on clients that came after, like
             | Sublime Merge.
        
         | skrebbel wrote:
         | Wow, I'm absolutely blown away, this is what I want a Git UI to
         | be.
         | 
         | But I'm not on Mac, does anyone know of a tool that has a
         | similar design idea behind it that works on Windows or Linux?
        
         | arxanas wrote:
         | Nice, this is really cool. Similarly, I had to implement extra
         | plumbing on top of Git to make snapshotting possible. I'll
         | update the blog post with a reference.
        
           | swisspol wrote:
           | GitUp uses libgit2 under the hood. GitUpKit is an Obj-C
           | wrapper I wrote at the time to make it much easier to use.
           | 
           | Unlimited undo / redo is achieved by taking a snapshot of the
           | entire repo before and after any operation (e.g. checking out
           | the repo or creating a branch etc...). The inspiration I had
           | at the time was that is it is trivially cheap to take such
           | snapshots: essentially all you need is a list of all the
           | refs.
           | 
           | Then when you need to undo, you have 3 things: 1 - current
           | state of all the refs in the repo 2 - state of all the refs
           | from the before snapshot 3 - state of all the refs from the
           | after snapshot Compute the delta between 3 -> 2 and apply on
           | top of 1.
           | 
           | The same technique allows to do the Time Machine feature.
        
       ___________________________________________________________________
       (page generated 2021-06-21 23:00 UTC)