1. 59
  1.  

  2. 19

    Random tip: like cd -, git switch - switches to the previous branch.

    1. 20

      git checkout - does the same.

      Also, both commands were added in 2019; so it’s not that new. I never used it though; git co is hard-wired in my brain now.

    2. 7

      git-checkout(1) is truly a very misleading command due to its various possible meanings (same with C static keyword). I hope these commands could make the situation better but I think it might be a lost race as git-checkout is already very established in the workflow of many users.

      1. 5

        I hope these commands could make the situation better but I think it might be a lost race as git-checkout is already very established in the workflow of many users.

        I think framing this as a “race” is kind of a false dichotomy; these commands can improve the ergonomics for people who find checkout confusing. I won’t be switching, but that’s because checkout’s behaviour has always felt intuitive to me, which is why it’s firmly established in my workflow.

        The new commands broaden the friendliness of git, they’re not “losing” just because I personally have no need to take them up. It’s not one or the other.

      2. 7

        To be clear, these are 2 years old. They’re great additions and I use them daily, but “new to git” is misleading.

        1. 9

          I’d never heard of them before, even though I use git on the command line on a daily basis. For me, I know checkout, but explaining to co workers, switch is a lot easier.

        2. 7

          Having multiple ways to achieve the same result is only one of the reasons why I can’t stand Git.

          1. 3

            As someone who spends an unreasonable amount of time thinking about CLIs, it seems the main reason for all the confusion initially was just that in git checkout <tree-ish> -- <pathspec> the <tree-ish> allowed a default value. I wonder if that hadn’t been the case (you has to specify a branch/ref at all times) if the same confusion would have happened.

            1. 6

              The thing that strikes me as semantically muddled is that if you provide <pathspec>, it doesn’t change what branch/commit you have checked out, it just modifies files in the working directory. But if you don’t, it moves you to a different branch/commit.

              1. 1

                I think the thinking is that moving to a different commit is just modifying the working directory. You’re just modifying it it look like whatever the tree you specify is.

                1. 7

                  It isn’t ‘just’ changing the working directory though, there’s a branch pointer that keeps track of where you are in the history, reflected by git status.

                  $ echo A > foo.txt
                  $ git add foo.txt
                  $ git commit -m foo.txt
                  [main (root-commit) b6197ed] foo.txt
                   1 file changed, 1 insertion(+)
                   create mode 100644 foo.txt
                  $ git checkout -b newbranch
                  Switched to a new branch 'newbranch'
                  $ echo B >> foo.txt 
                  $ git commit -am 'Add a line'
                  [newbranch a65b94d] Add a line
                   1 file changed, 1 insertion(+)
                  $ git checkout main foo.txt 
                  Updated 1 path from 46733b9
                  $ git status
                  On branch newbranch
                  Changes to be committed:
                    (use "git restore --staged <file>..." to unstage)
                  	modified:   foo.txt
                  
                  $ git checkout main
                  Switched to branch 'main'
                  $ git status
                  On branch main
                  nothing to commit, working tree clean
                  
                  1. 1

                    OK yeah, it changes HEAD, but defaults to keeping it the same.

                    So the summary is that it moves HEAD to whatever you specify, or leaves it unchanged if you specify nothing, and updates the working directory to reflect the move, filtered by a path list that you specify after --.

                    1. 3

                      Note that in the example above, git checkout main foo.txt does not change HEAD, despite having explicitly specified a branch (main). If pathspec is included, specifying a branch explicitly just influences where to get the files from.

            2. [Comment removed by author]

              1. 6

                The notion of a “new commit” is relative; a commit can only be understand to be “new” in the case that you have exactly one remote

                Are you sure it’s this complicated? I just took it as “any commits after the switch are added to this branch.”

                1. 1

                  oh jeez I’m a dope. I took this as being a rebase alternative, I thought it was switching the branch of the commits. This could of course been remedied by actually playing with it.

              2. 1

                I often use git restore -p to interactively discard uncommitted changes.