6 ms·
I don't use git at work, but in my private hobby projects my friends usually get mad when they watch me juggle changes and branch pointers with git reset --hard
by MauranKilom 3y ago
I don't use git at work, but in my private hobby projects my friends usually get mad when they watch me juggle changes and branch pointers with git reset --hard and git stash...
How do you undo a merge that you didn't mean to do/did wrongly?
git reset --hard <last commit before merge>
Have some cosmetic fixups on your local branch that really should go into main (or a separate branch) first before merging a bigger feature?
git stash
git checkout main
git stash apply
By thinking about branches as pointers, the commit graph existing independently, and stashes just being temporary commits, I feel I'm working much more directly with the underlying abstraction. Yes, git has commands for specific combinations of actions, but for an occasional user it's harder to remember every such command and which arguments and flags to pass in which order. It's either "look through documentation until you find graph diagrams illustrating what will happen for this order of arguments and flags" or "use the primitives 'move branch pointer', 'commit to branch', 'hold these changes for a second' for obtaining the commit tree you actually want. Knowing that the reflog exists also makes this insane-sounding working mode pretty non-scary. And yes, some operations (e.g. cherry-pick) you just need to do the "real" way.
(My git stash obsession is most likely just damage from years of using Perforce, which doesn't have a modified/staged distinction. The only way to commit only part of a changed file is via the equivalent of stash -> [restore half the file] -> commit -> stash pop.)
Prepares to be crucified...
- globular-toast 3y ago"Undo" is usually more like `git reset --hard HEAD@{1}`, ie. using the reflog. Nothing wrong with this at all. Only people who don't understand and/or are scared of git don't like it. You could also use cherry-pick to "donate" commits to other branches, instead of stash, of course. Magit has some great extra abstractions for this.
- hotnfresh 3y agoYou can check out multiple branches in different directories from a single git repo. This saves me a lot of what used to be stashing.
- bshacklett 3y agoI’d be interested to hear more about your workflow I’ve thought about doing similar things, but it just seems like too much overhead.
- hotnfresh 3y agoGreat to have two “work trees” when you’re often called in to troubleshoot or help with other branches. Sometimes handy during merges, too.
- zaptheimpaler 3y agoBoth of those sound totally reasonable to me! I don't know of any better ways to do that stuff and there's nothing risky about it.
- int0x80 3y agoOne thing that is risky about git reset --hard is that any non-committed changes are lost. That has bitten me a few times.
- LtWorf 3y agoCompletely reasonable if you do on your local branch, or if you have a convention that remote branches starting with your name or something are yours only. If you rewrite history on master… well… completely unreasonable.
- specialist 3y ago> I'm working much more directly with the underlying abstraction Your strategy of seeing things as they are is a useful general purpose life skill.
- codesnik 3y agowhy crucified? you're doing exactly what I do. All the people who have any trouble with git whatsoever try to use it as a black box for some high-level whatever ideas of what is their workflow should be. And git is not that, git is a thin wrapper around simple and elegant data structure. If you understand it, then everything clicks and git doesn't EVER gives any trouble. Your friends are unreasonable, unless you collaborate with them on the same branches and rewrite them after you shared them.
- codesnik 3y agoalso, using stash is only a first level. git cherry-pick, git rebase --interactive, git reset --hard HEAD^ and friends allows do such moves and cosmetic extractions after the commit itself. I also prefer to split cosmetic changes and feature changes, so I extract cosmetic stuff to the main all the time.
- tremon 3y agogit reset --hard is actually dangerous, because it throws away local modifications that were not yet committed. To undo just the commit and not the work, you should use git reset --soft (to undo just the git commit) or git reset --mixed (to undo both the git commit and the "git add"s leading up to the commit).
- alex_smart 3y agogit checkout will also happily throw away local unstaged modifications, and I would argue that it is even more dangerous because I did not have to type "--hard" to shoot myself in the foot.
- hnarn 3y agoThat does not sound right at all, I’m pretty sure there’s a warning when you try to checkout a branch that would override local unstaged changes. I might be wrong but I’d like some proof.
- Izkata 3y agoCheckout is also used for reverting changes to unstaged files.
- chlorion 3y agoIn some repo you have, make some changes to files that are tracked. Git status will show you "changes not staged for commit: <more stuff>". Run "git checkout .", and check the status command again, it will be in a clean state. >git status On branch feature/redacted Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: redacted.py no changes added to commit (use "git add" and/or "git commit -a") >git checkout . Updated 1 path from the index >git status On branch feature/redacted nothing to commit, working tree clean
- alex_smart 3y agogit checkout is overloaded and has two use cases. git checkout $branch is safe, git checkout $file_or_folder_name will help you shoot yourself in the foot.
- afiori 3y agoI agree that git is almost asking you to juggle commits. My preference is to use temporary branches and cherry-picking instead of stashing; I mostly use a gui* to work with git so it is easy to select the two or three commits to cherry-picking or see visually if an interactive rebase would work. * https://gitextensions.github.io/ https://gitextensions.github.io/
- pitaj 3y ago> How do you undo a merge that you didn't mean to do/did wrongly? I usually used `switch` for this: # Check out the previous commit git switch -d HEAD~ # Overwrite the branch git switch -C <current branch>
- erik_seaberg 3y agoNot a fan of the staging area, because it won't be tested. I would rather stash some changes to postpone them, then test and commit the workspace.
- thiht 3y agoWhat does the staging area has to do with tests?
- erik_seaberg 3y agoWhen the workspace and the staging area aren’t in sync, the differences cannot be tested because the compiler doesn’t know how to deserialize the .git/index blob. The workspace is stored as normal source files, and committing those would be better.
- bshacklett 3y agoThat would remove a huge amount of flexibility from the commit process, though. git add -p (and its siblings) are a huge part of my workflow. I often work on multiple changes at once, but break them out into their own atomic commits with the ‘-p’ flag. What would be great is a simple way to have build/lint/etc. tools look at the staging area instead of the workspace.
- erik_seaberg 3y agoFor what it’s worth, I didn’t have much trouble switching from “git add -p” for changes I want now to “git stash -p” for changes I want later.
- bshacklett 3y agoI’ll definitely give that a try
- Kuraj 3y agoNah I do that too. I also amend and push --force to my private branch a lot to make the git history easier to follow for whoever is going to do a code review.
- thiht 3y agoI do that too (except I use a soft checkout instead of —hard, I prefer to review and delete the reset changes myself). I tried using git worktree for a while when working on multiple branches, but it’s a pain to use… Stashing is easier.