Live data from Hacker News

Idiot Proof Git

softwaredoug.com

381–390 of 435 posts

Re: Idiot Proof Git

#381
post #322
post #294

Earlier quoted context omitted.

git add . We have had multiple security incidents because some developer left a credential file inside the local git clone (no, not all tooling supports out-of-tree stored credentials). Blind 'git add .' is the first thing I teach my developers not to do.

git add . is very useful though. Surely, the first thing to teach here is to always git status before committing? My typical workflow is to git add . to see the mess I’ve made then decide how to clean it up. If I’ve mistakenly added a credentials file, the fix is to add it to the gitignore and unstage it, not JUST unstage it. Not saying that you shouldn’t do both, but maintaining a gitignore and completely removing t…

If you can tolerate a GUI, Git Cola might be a solution. I'm using it exclusively for some 5 years now – it's lightweight enough, but still makes you think about what you're about to commit. You can add things to .gitignore directly from there, too.

https://git-cola.github.io/

Default layout is a bit weird IMO, here's what I'm doing instead: https://u.ale.sh/my-git-cola-screenshot.png

Re: Idiot Proof Git

#382
post #265
post #216

Earlier quoted context omitted.

gosh, wow, I want the opposite of that for any project I work on. In the last five years I have never used a merge commit and I love it. I'd honestly prefer a version of git that doesn't have em.

Without merge commits you can never have more than 1 long-lived branch because said long-lived branches will not have any common ancestors which makes pulling changes between them a nightmare (literally every file will be in conflict)... I like linear histories too, but if you have a production branch and a development branch you need merge commits between them.

I don't think either of those is necessarily true. I don't ever need to merge long lived branches if I don't want to. And I definitely don't ever merge my production branches with... anything. They are always just a fast-forward from another branch.

Re: Idiot Proof Git

#383

Earlier quoted context omitted.

I agree with most of this, except: > 5. When merge happens a dev's PR is squashed into one commit that gets appended to `main` I don't know if GitHub supports this, but GitLab has a semi-linear history feature. When enabled, it won't let you merge unless a fast-forward merge is possible, but it never does a fast-forward merge. This give you (IMHO) the best of both worlds: your history is pretty linear and easy to rea…

What do you mean? Dev 1: "I would like my PR to make 2 commits into `main` instead of the 1 that everyone else gets via squash." Dev 2: "Ok then make 2 PRs."

It's reasonable to want a series of commits (or patches) to be pulled together, assuming they are well-organized commits.

Re: Idiot Proof Git

#384
post #380

Earlier quoted context omitted.

What do you mean by idempotent? Clicking undo two times and going back only one step sounds confusing.

> What do you mean by idempotent? For every git command, provide a way to undo the previous command, if possible. For example, `git checkout -b abc`, a `git undo` would execute `git branch -D abc`. This is just an example, I know you can find many problems and with this approach and edge cases when it doesn't work, but we can make life easier for beginners in most cases. > Clicking undo two times and going back only…

https://www.merriam-webster.com/dictionary/idempotent

idempotent means that doing it twice gives the same result as doing it once. So it seems you meant a different word?

Re: Idiot Proof Git

#385

Earlier quoted context omitted.

I understand the sentiment, but since git is probably one of the longer-lasting constants in our industry (if not the longest-lasting constant), I personally think it's really worth to have a bit of a look into it. Something I wish someone suggested to me years ago: Instead of trying to understand the commands, try to understand the datamodel. A branch is just a pointer to a commit, a commit is just a pointer (with m…

> Once you understood this (which really isn't any harder than, say, understanding how quick-sort works), going from the data-model to the commands is fairly easy, almost intuitive if it weren't for all the convoluted options that each command can take. So, not intuitive at all? I've had to make very minor changes to the commit history that took a bunch of obnoxious commands. I know the git model very well but it did…

> It would have been easier to copy all the source files out, check out the branch I wanted, then copy them all back in.

That would be "git checkout -b some-branch" and then "git reset --soft origin/main" (or whatever branch you want to be on top of).

"reset" sets the pointer where you want it to be, "--soft" ensures that the actual files on your filesystem (the working tree) isn't touched. You will then have uncommitted files (your changes compared to the origin/main), that you can then recommit everything the way you want it.

reset --soft is my goto-recommendation for devs who have to satisfy a linear history but don't really care about git-history at all. Just do your changes as you normally would, using merge and whatever else floats your boat, and then once you're done, just use a soft-reset and then commit everything in one single commit. It's of course not ideal (meaningful atomic commits or some such would be better), but compared to having dozens of "fix stuff" and "merge from main" commits, it's definitely better.

Re: Idiot Proof Git

#386

Earlier quoted context omitted.

I understand the sentiment, but since git is probably one of the longer-lasting constants in our industry (if not the longest-lasting constant), I personally think it's really worth to have a bit of a look into it. Something I wish someone suggested to me years ago: Instead of trying to understand the commands, try to understand the datamodel. A branch is just a pointer to a commit, a commit is just a pointer (with m…

You have misunderstood. It's not a case of not knowing more about Git and its toolset. It's about our underlying workflow, letting us do version control of our software with simple means instead of throwing everything at it. It's easy to throw a hammer, mallet, pein and a club all at once on a nail, but that doesn't mean it's necessary or helpful.

> letting us do version control of our software with simple means instead of throwing everything at it

VCS is a pretty difficult topic, and it's not like git is the only tool out there (let alone the very first). Multiple people potentially working on the same file in conflicting ways is always going to be something that cannot just magically be made simple. After all, if there are no conflicts, "rebase" is literally the simplest command there is - just "git rebase origin/main" or whatever your equivalent is and you're good. It's only with conflicts where the fun stuff starts.

Re: Idiot Proof Git

#387
post #279

Earlier quoted context omitted.

> And a linear history makes this much easier to analyze and understand, reducing cognitive load considerably. This, so much this! And the price you pay for it is a slightly more difficult "insert". We started to enforce linear history in one of our bigger repositories (about 100 devs) about two years back; the first months were quite the ride (I had to do plenty of support-sessions to recover 'lost' changes). But th…

You can, 99.9% of the time, emulate linear history with first parent history, which is a post-hoc tooling choice that doesn't remove context. Developers shouldn't try to merge branches with wip/wip/wip/wip histories either, that's just garbage. Commit messages are documentation, fix your documentation before you publish.

> You can, 99.9% of the time, emulate linear history with first parent history

Fully agreed, but that requires first of all to understand how this works and second requires you to run commands locally. If you're unfortunate enough to have to use e.g. bitbucket-server at work like I do, you'll always see the full graph, there which is A LOT easier to grok if it's linear. And since that's what's most devs look at (instead of git-log using some extra options) and also where CI-state happens to be reported (green/red build), that's worth a ton :)

Re: Idiot Proof Git

#388
post #265

Earlier quoted context omitted.

Without merge commits you can never have more than 1 long-lived branch because said long-lived branches will not have any common ancestors which makes pulling changes between them a nightmare (literally every file will be in conflict)... I like linear histories too, but if you have a production branch and a development branch you need merge commits between them.

long lived branches are an anti pattern so this sounds like a plus to me

I’d rather wait until a project is finished, than to push incomplete changes that (I hope) aren’t reachable.

But a long-lived branch needs to be rebased before review, because conflict resolutions need to be reviewed. In fact reviewing the version without the conflict resolutions is a waste of time, because that version probably won’t ever be deployed.

Re: Idiot Proof Git

#389
post #356

IMHO the single most important idiot proof of git should be a universal "undo" command. - Committed wrong? Undo - Switched to wrong branch? Undo - Pushed wrong? Undo - Merged wrong? Undo - Wrong reset? Undo There should be a "idempotent" undo for every action in git. If not, warn the user for possible outcomes. In this way, we can safely learn git via trial & errors.

That's not a bad idea. Pushed wrong is pretty hard to recover from (since you often aren't allowed to rewrite history on the remote), so I don't think there could be an easy 'undo' action for that, but the other ones could potentially be done.

If the result of the undo is that the remote branch (say main) is back at the point where it was just before, then that is actually a kind of change one could allow? As it does not rewrite history, just reset to previous point in time.

But to really support this well, I think git would need a git commit object which means "reset to previous state".

Re: Idiot Proof Git

#390
post #357
post #356

IMHO the single most important idiot proof of git should be a universal "undo" command. - Committed wrong? Undo - Switched to wrong branch? Undo - Pushed wrong? Undo - Merged wrong? Undo - Wrong reset? Undo There should be a "idempotent" undo for every action in git. If not, warn the user for possible outcomes. In this way, we can safely learn git via trial & errors.

> In this way, we can safely learn git via trial & errors. Thinking about this and I realize it could be beneficial in a lot of software. No one RTFMs anymore, and giving them the ability to trial and error makes sense. I know I appreciate it (pushing buttons to see what happens), but I’m not sure how common this approach is in general.

Being able to undo an action is is actually a general usability principle that has been around at least since the 1980s :-).
Post reply on HN