
Highlights from Git 2.23 - digitalnalogika
https://github.blog/2019-08-16-highlights-from-git-2-23/
======
mhd
I really need some kind of "modern git" tutorial. A lot of what we're doing
day to day stems from the earlier days of the software (and SO posts from that
time), and I bet there's plenty of new options that would make something
easier or even enable different workflows. I just recently learned about "git
worktree", for example.

------
nemetroid
I'm wary about git restore --staged. It seems backwards to have a destructive
(worktree-modifying) command become non-destructive by adding a flag. To me,
this appears more footgun-prone than git reset, which defaults to non-
destructive behaviour and requires the ominous --hard flag in order to become
destructive.

So I will probably avoid both git restore --staged and git reset --hard (and
suggest to others to do the same). I hope git status will keep the hint to use
git reset to unstage, even after git-restore becomes stable.

~~~
dfabulich
Yeah, it's mirroring the behavior of "git checkout -- myfile" which also does
destructive changes without warning.

These new commands were hatched in response to a blog post from a couple of
years ago pointing out the confusion. [https://redfin.engineering/two-commits-
that-wrecked-the-user...](https://redfin.engineering/two-commits-that-wrecked-
the-user-experience-of-git-f0075b77eab1)

A good conversation on HN followed.
[https://news.ycombinator.com/item?id=14712269](https://news.ycombinator.com/item?id=14712269)

I've long wished git checkout (and now, git restore) would save the contents
of blown-away worktree files somewhere (e.g. a throwaway stash) so that they
could be retrieved from the reflog or something.

In my mind's eye, the command would be something like "git trash" and it would
throw your changes into a trash can, where you could fetch them back out again
later, until the GC erased them in ~30 days or so.

~~~
ryanianian
> have the contents of blown-away worktree files somewhere

This would be an _amazing_ feature for nearly all git commands that affect the
worktree. Many times I've done `git checkout ./src` to blow away "unrelated"
files forgetting that the file I was just working on was in that directory.
Whenever I teach git to a new-hire I always talk about wanting revision-
control for revision-control.

~~~
codetrotter
I think people trip on these potential foot guns in part because a lot of git
commands are long and annoying to type, so you end up working more based on
your mental model of the state of the working copy and less based on the
actual state of it.

I am not so fond of analogies but I would like to offer up an analogy here
anyway. I think for a lot of people, the way that they are using git is akin
to utilizing a sharp knife with your hands while your hands are obstructed
from your view. You have a certain amount of feeling for what is going on but
you are bound to cut yourself now and then if your view of what you are doing
is obstructed. In this analogy, your reliance on your mental model of the
state of the working copy is obstructing your view of the reality of the state
that it is in.

Several years ago I defined a few two-letter shell aliases for the git
commands that I use the most.

Maintaining my .bashrc across different systems became a drag though, so I
simplified my setup even more.

I wrote two-letter “shell scripts” that just wrap the commands, and just put
those in my ~/bin/. This makes it very fast and simple to get up and running
on a new laptop, desktop or server.

[https://github.com/ctsrc/shell-command-
aliases](https://github.com/ctsrc/shell-command-aliases)

Said two-letter shell scripts can be found in that repo. There’s a README too,
which tells you what each of them do.

My git workflow is simple, efficient and ensures that my view of what I am
doing is not obstructed.

I can proudly say that the last time I did something unintended with git that
resulted in lost work was long ago that I can’t even remember when. And it all
boils down to these two-letter aliases.

When there is friction, identify the friction and remove it. That is what I
have done here. Hopefully it might be of use to others too.

Here are some consecutive entries from my bash history that are representative
of how I use my aliases while working on something.

    
    
        mv ~/tmp/index.htm dimensions.htm
        st
        ls
        dp
        git checkout -- src/
        st
        mv dimensions.htm src/
        st
        mv src/dimensions.htm src/draft.htm
        di
        st
        aa
        cm "Draft."
        le
        le
        vim src/draft.htm 
        st
        vim src/draft.htm 
        aa
        di
        cm "Mirrored, dark/light."
        vim src/draft.htm 
        aa
        di
        vim src/draft.htm 
        aa
        di
        cm "Remove unneccessary declaration."
        vim src/draft.htm 
        aa
        di
        cm "Organize and restructure classes in draft."
        vim src/draft.htm 
        aa
        di
        cm "Increase height of placeholder."
        pu
        le
        st
        st
        dp
        vim src/draft.htm 
    

I keep a few terminal windows open when I work on a project, and often use one
or two of them for git operations, and smaller edits to some files, while also
having my IDE open, web browser, etc.

Notably, these two-letter commands make it very fast to remind myself of what
the current state of the repository is whenever I've looked something up on
the Internet for example, or after I have run tests in another terminal or
made multiple different edits in different files in the IDE window, etc.

And I always check the diff before I commit. It's amazing how often you think
you are about to commit just one change but when you look at the diff you
realize that there are some other smaller changes that you made as well. By
always reviewing your diff before you commit, you ensure that you don't commit
something that would be better committed separately, and that your commit
messages accurately describe the actual changes that you are committing.

~~~
ReidZB
I do something similar, though I use git's built-in aliasing so that I keep
everything namespaced under "git". Mine are, for example, "git st" (status),
"git ci" (commit), "git co" (checkout), "git dfc" (diff --cached), etc.

That said, my best advice for folks new to git, or folks who find themselves
doing destructive actions often, is to embrace WIP commits. I "checkpoint"
work somewhat frequently with "git add -A; git ci -m wip". They can be cleaned
up later with soft resets, rebases, or similar. Once a commit is created, it's
in the reflog, and it's quite rare to lose that set of work, even if a rebase
or reset goes "wrong".

------
kissgyorgy
This is still far from ideal. "git switch" and "git checkout" should not be
able to create a new branch. It clearly should be the "git branch"
subcommand's responsibility, because "You want to do something with a branch".
It would be two commands to create and checkout a new branch, but less
confusion. You can use your git alias anyway. But a shortcut for "git branch
-c" would be better if you want to keep the "create and switch" shortcut IMO.

~~~
int0x80
I disagree. I found git checkout -b very convenient an intuitive way to say
"create and checkout this branch".

For git branch -c one could say that the "branch" command should not do
checkout-business.

~~~
sametmax
I should be a separate cmd. It's such a common operation, and it's a huge noob
trap.

~~~
nemetroid
The reason it's a noob trap isn't that the two operations should be separate.

The issue is that "-b" (mnemonic for "branch") in no way suggests that it
creates a _new_ branch. Since checkout does so many different things, it would
be reasonable to guess that -b limits the command to perform the "branch"
action (i.e. switch to a branch). Git-switch doesn't have this issue.

------
saagarjha
It's nice to hear that there appears to be progress being made in making git's
tooling nicer and more consistent. Git's model itself is pretty simple, but
the command line tools for working with it aren't and I feel that this fuels
most of the "Git is hard" complaints.

------
tomasyany
On the one hand I'm happy on the new "switch" and "restore" commands. On the
other hand I wonder if they truly add any value other than the semantic
distinction of functions otherwise present in "checkout".

I tend to prefer smaller vocabularies tools: less to remember if you know what
you are doing.

~~~
Smaug123
I would argue that it's not really increasing the vocabulary. The fact that
one word has (say) seven meanings doesn't mean the vocabulary you must learn
is one word. It's still seven words, which happen to be spelt and pronounced
the same way.

------
Ayesh
Similar to GUI apps that work on top of git binary, does anyone know a user
friendlier CLI app?

It can have new commands:

\- `gitlite create` vs `git init`

\- `gitlite branch create feature-dom` vs `git checkout -b feature-dom`

\- `gitlite time-travel cfae736` vs `git checkout cfae736`.

\- `gitlite undo cfae736` vs `git reset cfae736 --hard`

\- gitlite release create v4.2` vs `git tag v4.2`.

Each command will call the translated `git` command, and perhaps improve upon
the output from the command.

