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.
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
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.
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".
I wish I could move HEAD to a different commit (git reset), and apply (new HEAD - old HEAD) to my working directory (--hard), but abort if working directory != old HEAD.
In fact, this sounds like `git reset --keep`, but unfortunately prezto doesn't have an alias for that.
I don't like prezto's git-reset aliases. gwr is "move HEAD", gir is "move HEAD and reset index", and gwR is "move head, reset index, and reset working directory". I wish gwr was renamed to ghr, and maybe gar (git apply reset) for --keep.