5 ms·
Highlights from Git 2.23
- nemetroid 7y agoI'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 7y agoYeah, 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-experience-of-git-f0075b77eab1 https://redfin.engineering/two-commits-that-wrecked-the-user... 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.
- justsubmit 7y ago> 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. Magit can do this. See https://magit.vc/manual/magit.html#Wip-Modes https://magit.vc/manual/magit.html#Wip-Modes
- ryanianian 7y ago> 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.
- sjburt 7y agoI've always felt like an inotify-based system that made invisible/anonymous commits every time the filesystem changed would be a great extension of the git commit workflow. You could then browse these and choose to make a "real" commit, or jump back to any point.
- codetrotter 7y agoI 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.
- gregmac 7y agoI agree, and it would be great if git adopted the general philosophy that it would never do a destructive change without stashing it in "trash" first. This could even go as far as adding a "git undo" command.
- yjftsjthsd-h 7y agoAs a comparison, mercurial seems to do this; if you revert an uncommitted change, it makes a "*.orig" file. (Mercurial generally is more obsessed with never losing anything than git, such as its refusal to delete commits)
- chongli 7y agoMercurial generally is more obsessed with never losing anything Which is silly, because people often commit sensitive data such as private keys or customer's personal information. Sometimes you really do need to delete a commit (or worse, a file that lives through a long history of commits).
- saagarjha 7y agoIt'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 7y agoOn 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 7y agoI 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.
- deleted 7y ago[deleted]
- kissgyorgy 7y agoThis 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.
- wodenokoto 7y agoBut I want to switch to my new branch. One of these commands will have to do double duty. Either switch/checkout will create or branch will switch. I don’t see why choosing one for double duty is inherently worse than the other. But I do consider your proposal of `git branch —create` as a poor command for create and switch branch.
- masklinn 7y agoFWIW in their proposal `git branch -c` would be `git branch --checkout` not `git branch --create`, which is what `git branch <name>` does. The `git checkout -b` and `git switch -c` docs specifically note that they're shortcuts for going a git branch then a git checkout/switch.
- mewse 7y agoI'm sure it's not what they were intending, but 'switch' used to be a pretty common term for a light, flexible branch. And all of git's branches are pretty light and flexible, at least compared against the branches of the previous generations of version control systems.. But yeah. That's definitely not what they were intending.
- int0x80 7y agoI 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.
- 7y ago
- mhd 7y agoI 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.
- Ayesh 7y agoSimilar 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.