News for hackers. Stuff that matters.
Re:Oh shit, git: Getting myself out of bad situations by falcolas on Monday December 18, 2017 @10:48AM (#15952387)
A git off my lawn moment: Every time I see someone complaining because they have to dive into the reflog to fix their own mistake, all I can hear is "I was operating my table saw without using a push stick and can't understand why I lost a thumb".

Friends don't let friends (especially those who don't learn how to use their tools) rewrite shared git history. If you don't understand rebase, amends, etc can do to your (and everyone else's) repo, DON'T DO IT.

Re:Oh shit, git: Getting myself out of bad situations by AlexCoventry on Monday December 18, 2017 @10:58AM (#15952477)
On the other hand, doing it is the only way you're going to learn. Just do it in a safe environment, with a snapshot of the repository.
Re:Oh shit, git: Getting myself out of bad situations by jsmthrowaway on Monday December 18, 2017 @02:00PM (#15954290)
Yep. That is the important tip, right here.

    $ pushd ..
    $ cp -a my-project my-project-before-I-did-git-surgery
    $ popd
Then relax. This is extremely important before playing with nasty Git surgical tools such as huge rebases. Borked it up?

    $ pushd ..
    $ rm -rf my-project
    $ cp -a my-project-before-I-did-git-surgery my-project
    $ popd
Undo is a great thing, and it's also important to triple check the entire state of the repository before you push, because pushing is basically committing to whatever surgery you've done. If you're having to fix stuff with -f, you're going to run into trouble; try to avoid -f ever.
Re:Oh shit, git: Getting myself out of bad situations by xaphod on Monday December 18, 2017 @03:52PM (#15955396)
This is so wrong. :) With git you exactly do not have to backup your local workspace, because it already is backed up in git.

If it is committed, it is safe. You can go back to it. If you messed up your branch, just reset it to something that was good. No need to do manual backups.

Re:Oh shit, git: Getting myself out of bad situations by bpchaps on Monday December 18, 2017 @04:10PM (#15955537)
Sure it's wrong if you know what you're doing. But that's not who the blog post is for.

Sometimes it's okay to take liberties with good practices - especially when learning, or when the world is on fire and a push needs to happen now.

Re:Oh shit, git: Getting myself out of bad situations by richforrester on Monday December 18, 2017 @05:22PM (#15956051)
> or when the world is on fire and a push needs to happen now.

The unwanted reality we live in.

Re:Oh shit, git: Getting myself out of bad situations by jsmthrowaway on Monday December 18, 2017 @04:06PM (#15955508)
No, it isn't, if you're playing with surgical tools that disrupt Git history, which was my point. It's a lot easier to revert to before you started than attempt to abort out of a huge rebase/squash/ugly merge conflict hell/rewrite of history. I'm not saying back up before every commit. I'm saying when `git status` is three pages long, you have 14,000 conflicts, and you're on a detached HEAD God knows where, it's your choice to spend the next hour typing the right Git commands to get back where you wanted to be, or just back out and try again. I know which one I'd prefer.
Re:Oh shit, git: Getting myself out of bad situations by xaphod on Monday December 18, 2017 @05:43PM (#15956169)
I'm sorry if I sound rude. I don't mean to be. I'm just saying that backing up your git workspace to recover from rebases or merges gone wrong is not necessary. Those are not "surgical tools", they don't modify existing commits. (edit: yes you can "edit commits", but they only create new commits, the old commits are not deleted in the process and they can still be found easily)

When you commit in git, that saves the whole project as a "snapshot". If you find yourself lost in some rebase hell or whatever, just reset HEAD back to a previous commit. It's simple as that! (git reset --hard <commit>)

Why I decided to reply to your comment was because this is a very crucial part of learning git. When you realize that you can always go back to what was before, you can start experimenting more freely.

Re:Oh shit, git: Getting myself out of bad situations by jsmthrowaway on Monday December 18, 2017 @05:58PM (#15956260)
> git reset --hard <commit>

Unless part of your surgery involves files that do not yet live in the history, or you're working on a detached HEAD in a mid-merge state, or... git reset --hard is a very dangerous operation unless you're 100% sure of the entire state of the repository. That is a very rapid way to lose work if you're not perfectly diligent.

And sure, you shouldn't have to back up .git or your workspace, but sometimes, it's a hell of a lot easier to ripcord out and say "screw it" if you have a complete workspace from before you decided to launch down the rebase hole or whatever.

Re:Oh shit, git: Getting myself out of bad situations by u801e on Monday December 18, 2017 @07:56PM (#15956917)
You could run git reset without the --hard parameter to keep unstaged changes in the working directory
Re:Oh shit, git: Getting myself out of bad situations by minor3rd on Monday December 18, 2017 @06:27PM (#15956402)
It's only easier to copy the directory if you haven't done the due diligence of learning git properly. It's a tool to avoid doing the ripcord approach -- ever.
Re:Oh shit, git: Getting myself out of bad situations by iamjaredwalters on Monday December 18, 2017 @08:58PM (#15957167)
Why not just create a new branch instead of copying your project over to a new dir?
Re:Oh shit, git: Getting myself out of bad situations by palunon on Monday December 18, 2017 @03:01PM (#15954929)
>If you're having to fix stuff with -f, you're going to run into trouble; try to avoid -f ever.

I disagree. I don't have much experience using git with big teams, but at least for small team where a developer usually owns a feature branch, force pushing to the branch to take into account criticism on commits can be helpful. Of course, in that case, feature branches are considered non shared.

Git own "next" branch is actually force pushed to all the time, to remove patches which didn't make the cut for example.

Re:Oh shit, git: Getting myself out of bad situations by falcolas on Monday December 18, 2017 @07:04PM (#15956658)
Personal opinion - re-reviewing a pull request when someone has erased all context from your last review of that PR via a rebase and force push is a royal PITA. Especially for changes that span more than a few files. Did they address your concerns? The only way to know is to go back through all of the changes on that feature branch, and hope you don't miss anything.

This, in contrast with just reviewing the latest commit, potentially going back to the rest of the changes with an eye towards the latest commit.

It frankly bugs the piss out of me when people rebase and ask me to review their latest changes - it feels disrespectful of my time.

Re:Oh shit, git: Getting myself out of bad situations by gwright on Monday December 18, 2017 @09:09PM (#15957213)
I've taken to making the change as a fixup commit and leaving it in the PR for code review. Then when the changes are approved a quick `git rebase -i --auto-squash` cleans everything up before merging the branch back into `develop`.
Re:Oh shit, git: Getting myself out of bad situations by jsmthrowaway on Monday December 18, 2017 @04:08PM (#15955522)
> force pushing to the branch to take into account criticism on commits can be helpful

Hm? Criticism on commits should be additive. The commit was made, response was made, and a new commit addresses the response. Rewriting history breaks a lot of things and removes context. Another approach:

1) Add commit addressing criticism.

2) Squash when merging feature in to master, which is one of the only cases where I think rewriting history is OK.

Much cleaner master history, no rewriting history (which you should never do once another checkout sees your branch, including GitHub), and a number of other benefits. If you're routinely force pushing feature branches, something is broken in your workflow, IMO.

Re:Oh shit, git: Getting myself out of bad situations by flowardnut on Monday December 18, 2017 @11:14AM (#15952637)
practicing safe version control is better than abstinence
Re:Oh shit, git: Getting myself out of bad situations by pretentiousPear on Monday December 18, 2017 @01:30PM (#15953948)
I see what you did there...
Re:Oh shit, git: Getting myself out of bad situations by rkangel on Tuesday December 19, 2017 @06:59AM (#15959521)
This is a place where Mercurial wins out. Hg has the concept of phases that makes it much harder to screw up rewriting history:

https://www.mercurial-scm.org/wiki/Phases

Re:Oh shit, git: Getting myself out of bad situations by falcolas on Tuesday December 19, 2017 @09:42AM (#15960499)
Replacing a table saw with a circular saw (bad analogies abound) doesn't remove the opportunities for losing appendages. Especially for those who don't learn how to use the tools put in front of them.

"It is impossible to make anything foolproof because fools are so ingenious."

Yes, Git is a sharper tool with fewer blade guards than other version control systems, including HG. That sharpness and relative lack of safety mechanisms, however, lets you do things you can't in other systems. The real problem is that folks use these tools without attempting to understand them and cargo-cult onto a workflow which leaves them open to screwing things up.

To continue the "git off my lawn" moment - I've had to use the reflog exactly zero times in the past few years, despite using rebase locally on a fairly frequent basis (and sadly remotely to fix other's bungles as well). This is only because I respect git for its sharp edges, and when it comes time to re-write history with rebase, I work carefully.

Re:Oh shit, git: Getting myself out of bad situations by leggomylibro on Monday December 18, 2017 @12:19PM (#15953274)
Reminds me of a time I saw a funny Makefile mistake. SRCS contained both .cpp and .c files, and someone copied a recipe that only replaced .c ones.

Then they used the resulting variable in 'make clean'. That was more of an, 'oh shit, git pull' sort of thing though.

Re:Oh shit, git: Getting myself out of bad situations by azernik on Monday December 18, 2017 @07:58PM (#15956928)
I use the reflog all the time to fix my own rebase mistakes; it's just on rebasing I've done locally, and where the results haven't made it out to a shared repo.
Re:Oh shit, git: Getting myself out of bad situations by Groxx on Monday December 18, 2017 @06:26PM (#15956400)
Rewriting shared history fits the metaphor pretty well.

But you can still chop off your thumb in your local history, and that's safe to fix - you just have to know where the duct tape is.

Re:Oh shit, git: Getting myself out of bad situations by swalsh on Monday December 18, 2017 @11:24AM (#15952738)
rebase can be dangerous, but so productive. I think it's important to teach new devs how to properly use it. Especially if you're working in a continuous deployment environment, where you may need to quickly revert something.
Re:Oh shit, git: Getting myself out of bad situations by falcolas on Monday December 18, 2017 @12:23PM (#15953308)
Reverting something does not require a rebase. It requires an aptly named command "git revert". Additionally, in the event that a deployed feature needs to be reverted, any halfway decent change management policy will want a history of what you reverted and why; a git revert commit can show both very cleanly.

And, frankly, since all rebase does is re-write history, I fail to see how it's inherently productive, especially in the context of re-writing the history of previously shared commits. Yes, it is capable of cleaning up and reducing the number of commits you have to read through when looking at history, but that's such a rare event that optimizing for it (especially by normalizing dangerous commands like `git push -f`) seems, well, premature.

Re:Oh shit, git: Getting myself out of bad situations by Yokohiii on Monday December 18, 2017 @01:10PM (#15953744)
Completely agree. Rebase is practically only safe on single developer feature branches which haven't been merged or completely isolated repos that produces patches only. Keeping track of all requirements in the former is hard, especially if the dev doesn't know git pitfalls. No one should default to rebase in a day to day workflow, but it is quite common.
Re:Oh shit, git: Getting myself out of bad situations by Sir_Cmpwn on Monday December 18, 2017 @12:54PM (#15953604)
Rebase is mostly useful for cleaning up local commits or feature branches. You can rebase without force pushing master.
Re:Oh shit, git: Getting myself out of bad situations by madeofpalk on Monday December 18, 2017 @11:35AM (#15952851)
driving can be dangerous, but so productive. I think it's important to each new adults how to properly use it.
Re:Oh shit, git: Getting myself out of bad situations by Nullabillity on Monday December 18, 2017 @12:17PM (#15953248)
You already have git-revert, for reverting commits without rewriting history.
Re:Oh shit, git: Getting myself out of bad situations by swalsh on Monday December 18, 2017 @01:05PM (#15953701)
You're misunderstanding the purpose i'm describing. Imagine 100 commits a day, maybe more. (I worked at a company that averaged 500 or more commits a day to the master branch. There were 1000 developers working in a monorepo). Some code is out in production, and suddenly we realize a specific commit is causing a problem. The idea here is to revert the commit as soon as you can, and then spend your time fixing it. When reverting code is easy, and the company has good logging to identify problems, you can deploy more often. It's a good thing.

But to enable this "revert-first" culture, you have to design your commits to basically be super easy to revert. That means no merges in the master branch, you want to keep your revision history as clean as possible. One commit, as little dependencies as possible. Rebase is the right tool to use for this. The goal is a tidy linear history.

Re:Oh shit, git: Getting myself out of bad situations by lmm on Monday December 18, 2017 @03:40PM (#15955297)
> But to enable this "revert-first" culture, you have to design your commits to basically be super easy to revert. That means no merges in the master branch, you want to keep your revision history as clean as possible.

How are these concepts related to each other? Merges don't make reverting any harder.

Re:Oh shit, git: Getting myself out of bad situations by Yokohiii on Monday December 18, 2017 @01:34PM (#15953996)
That sounds quite chaotic and impossible to keep stable. I wonder who was responsible to find problems and fix the master after messing up?
Re:Oh shit, git: Getting myself out of bad situations by swalsh on Tuesday December 19, 2017 @10:21AM (#15960776)
It was actually quite clean, and the environment was extremely stable. The trick is, every commit was "self-contained". Reverting it would go to another previous stable version. Creating a self-contained commit can be done many ways, and rebase is one common tool used to do it. Another is the use of git merge with --squash and a cherry-pick.
Re:Oh shit, git: Getting myself out of bad situations by drdrey on Monday December 18, 2017 @05:37PM (#15956135)
git revert is exactly the tool for the situation you are describing
Re:Oh shit, git: Getting myself out of bad situations by swalsh on Tuesday December 19, 2017 @10:23AM (#15960786)
Sorry again, you're not understanding my point. Git revert is of course used... but i'm not worried about the mechanics of the revert itself. I'm worried about each revert being a "self-contained" piece. That the project was stable after the revert. That's the bit that was important. A Linear history of commits is the important bit. Not how to do a revert.
Re:Oh shit, git: Getting myself out of bad situations by sirmarksalot on Monday December 18, 2017 @02:50PM (#15954825)
Git revert has undesired side effects for merges. If you have a merge-only workflow (GitFlow, for example), and your pull request breaks something, a revert commit will not help you.

After a revert, all the commits that were merged, are still merged, but then they're deleted. The next time you pull, git will delete the changes in your working branch.

In a merge workflow, you have to either fail forward (fix the problem, rather than backing out the merge), or reset/rebase the shared branch, and email repair instructions to everyone on the team.

Re:Oh shit, git: Getting myself out of bad situations by lmm on Monday December 18, 2017 @03:39PM (#15955286)
Create a feature branch, revert the revert, and then fix the problem. It sounds a little weird but it works fine.
Re:Oh shit, git: Getting myself out of bad situations by falsedan on Monday December 18, 2017 @03:45PM (#15955330)
It’s a lot of paperwork to avoid a perfectly safe and normal git command.
Re:Oh shit, git: Getting myself out of bad situations by lmm on Tuesday December 19, 2017 @08:43AM (#15960096)
No it isn't. You'd always want to create a feature branch so that you can PR the fix - it's a change going into master, it should go through the normal change-going-into-master review flow. And you'd always have to run some command to indicate that this was the branch where you wanted to undo what you'd done to master. That the command is called "revert" is a little weird, but it's no more paperwork than any other command would be.
Re:Oh shit, git: Getting myself out of bad situations by sirmarksalot on Monday December 18, 2017 @04:32PM (#15955705)
To be fair, rebasing a shared branch really isn't all that safe. You can potentially make life hard for a lot of people.
Re:Oh shit, git: Getting myself out of bad situations by falsedan on Monday December 18, 2017 @05:08PM (#15955964)
That’s not fair. That’s fear, uncertainty, doubt. Those people pulling that shared branch will see a big honking warning message, which can easily be resolved if you communicate what’s happening and why you rebased the upstream.

When you say, it’s not safe, it sounds like you could lose work or someone could be hurt, when it’s more likely that the removed ancestors could be merged back in by someone not using ‘git pull —rebase’, or other devs being put out by having to resolve some conflicts. It’s not great, but it’s a far cry from unsafe or DANGEROUS! MUST AVOID! PUBLIC SHAMING!

Re:Oh shit, git: Getting myself out of bad situations by falcolas on Monday December 18, 2017 @07:34PM (#15956798)
Anytime you normalize a workflow around using unsafe commands, you risk desensitization to those very warning messages you're relying on to save you.

If you have one rebase with a force push a week, people will quickly stop asking "who did the force push", since it has become normal. They'll instead just let the force push come through to their local repo, just to find out that the force push rolled the repo back a year. Now productivity is halted dead until someone goes in and fixes it and makes yet another force push.

The worst part to me is that it makes the repo lossy. The entire purpose of having version control is actively subverted in the name of "clean".

Re:Oh shit, git: Getting myself out of bad situations by falsedan on Tuesday December 19, 2017 @04:59AM (#15959078)
I think this is fine, but then I'm comfortable with what a force-push is (a remote reset) and I know that the commits still exist even when the ref is moved, and how to inspect the history of a bare repo to move the ref back.

I don't understand the business requirement for a non-lossy repo. In my experience, we need to be able to link a release to a specific commit, and we need to show that the changes were reviewed & tested before they were deployed. We use tags for this.

I also think the entire purpose of source control is to be able to answer question like "who changed this? when was it changed? why?".

> Now productivity is halted dead

Because of a bad push to a single repo? I really like the distributed nature of git, which lets me stay productive even when other repos and branches elsewhere are having issues. I would avoid treating git as 'SVN but newer'.