Live data from Hacker News

Lesser known Git commands

hackernoon.com

131–140 of 142 posts

Re: Lesser known Git commands

#131
post #52
post #37

> git it and empty root commit Why doesn't git init does this by default? It would be nice if every repo had an empty root commit (with no author, date,... so it has the same commit hash), then every two repos would have a common commit. Semantically it would mean that repos would be just specific branches of a hypotetical large repo.

You can already merge two divergent histories with the --allow-unrelated-histories option. (At the data level, merge commits don't care that their parents have a common ancestor, but the git merge command does this as a safety check.) In other words, all repos already are subsets of the ur-repo. The semantically-interesting data in git is not the commits themselves, but the branch names given to specific commits in s…

Interesting, now I learned that a git repo can have any number of commits that have no parents. It can be achieved by fetching an unrelated repo and merging with --allow-unrelated-histories or by using git checkout --orphan.

> safety check

Why is this considered unsafe? Only to avoid pulling from unrelated repos by accident? The man says for --allow-unrelated histories:

> As that is a very rare occasion, no configuration variable to enable this by default exists and will not be added.

Well this is quite harsh, it looks like it's considered to be rather unsafe.

Re: Lesser known Git commands

#132
post #117
post #112

Earlier quoted context omitted.

Brilliant! I wonder why git stash wasn't implemented similarly in the first place.

My hypothesis: git was implemented assuming that—at least for large projects—you would have a local on-disk bare clone of the repo, and then multiple workdir checkouts of that bare clone sitting on different branches. The setup with a single clone containing a workdir with a .git dir inside it is a hack that's nice for "on-the-go" use-cases, but wasn't intended for serious developers contributing many changes to the…

This is how you have to deal with branching in almost every scm. Changing branch might require you to rebuild something slow and then it's good to have multiple working directories. If you have monorepos you might also want to test component a on branch x vs component b on branch y etc.

If you are only working serially then switching branch in one working dir is obviously easier and to be preferred but some times you really need multiple checkouts of the same repo.

Re: Lesser known Git commands

#133
post #98
post #16

I've seen more stash accidents than any other kind with git. Stashing is more dangerous than committing or branching, and to me it doesn't seem to provide any advantages... do people actually find stashing easier than branching? Is it just because when you branch you have to name it, and that causes friction? I stay away from stash. Right from the man page: "If you mistakenly drop or clear stashes, they cannot be rec…

Do people really use stash for things they value longer than a few minutes? I've only ever used stash as a way to store changes that I made on the wrong branch. git checkout my_old_branch (wrong branch not realized yet) - work work work... git status - "oh, I'm on the wrong branch" git stash git checkout the_correct_branch git pull git stash apply (or git pop - but you lose what was on the top of the stash)

> Do people really use stash for things they value longer than a few minutes?

You'd be surprised. ;) Even a few minutes can get you into trouble though. The very last person I helped out of a stash crisis two days ago did exactly what you outlined, fully intending to stash pop immediately, and couldn't find his change and panicked.

What actually happened was he'd unknowingly stashed again during his branch switch, and his first stash was there, but not on the top of the stack. GitHub desktop was auto-stashing or something. (GitHub desktop has made several very strange choices...) Anyway when my friend applied an empty stash, he thought he'd lost his changes. He called for help on a Saturday, and I tried to point him in the right direction over email, but by the time I got to a terminal to see what happened, he'd already rewritten most of his change, having decided it was a loss.

OK, FWIW here are some safer alternatives to switching branches without stash:

- First thing to know is that you can switch branches with uncommitted changes in your working tree. You don't have to do anything else, git will protect against conflicts, so why not always try this first? It's less work most of the time.

If git complains, you can:

  git commit -am "WIP for the_correct_branch"
  git checkout the_correct_branch
  git cherry-pick my_old_branch
  git reset --soft HEAD^  # Optional, if you want to unstage
  ... Later ...
  git checkout my_old_branch
  git log
  ... Notice the leftover commit ...
  git reset --hard HEAD^
Or here's an alternative that doesn't leave the dangling commit for later:

  git commit -am "WIP"
  git branch work         # you can always do this with uncommitted changes
  git reset --hard HEAD^  # still on my_old_branch here
  git checkout the_correct_branch
  git cherry-pick work
  git branch -d work
If anything goes wrong with these workflows, my changes have been dropped in two branches, they'll be easy to find in the reflog, and the gc timer doesn't even start yet because they're still referenced. It's really hard to lose the changes this way.

The only option with the stash flow if the stash gets lost while switching branches is to use fsck, and the gc timer starts immediately because the stash is not referenced.

I mention the gc timer because some of the accidents I've seen are people popping stashes and only realizing later that they popped a different change than they thought they did.

They way this happens is people who are beginners to git. Once you know git, it's hard to imagine popping the wrong stash and not knowing it, but I've seen it happen multiple times. This is why I advise everyone to avoid stash - for beginners, it looks deceptively and attractively simple, but is easy to get in hot water. It's also another git subsystem to learn, as if git wasn't hard enough to learn. For git experts, it's so easy to avoid using stash, there are always safer alternatives.

Re: Lesser known Git commands

#134
post #16

I've seen more stash accidents than any other kind with git. Stashing is more dangerous than committing or branching, and to me it doesn't seem to provide any advantages... do people actually find stashing easier than branching? Is it just because when you branch you have to name it, and that causes friction? I stay away from stash. Right from the man page: "If you mistakenly drop or clear stashes, they cannot be rec…

I frequently swap between branches, for code review, or to move temporarily to something else for a short time. I decide whether to commit what I have done or whether to stash it for now, based on what state it is in. If I am still in the exploratory stage of the work, I usually wont commit, I will just stash and come back to it later. Its a useful thing to be able to do at time when i am not yet ready to COMMIT to t…

Of course I can't tell what your comfort level with git it. The more expert you are, the more it doesn't matter, and you can use stash safely.

I am not judging anyone or their workflows. It's the stash command that has the problem, because it circumvents git.

That said, my reaction to your comment is that you're taking "commit" too seriously. ;) Nothing in git is a commitment until you push. Nothing. If you haven't heard the phrase "commit early, commit often", consider that and take it to heart. If you have work you care about and even might want to save, then you should commit it. Git was literally made for the purpose of managing multiple versions of exploratory work -- to not use commits and branches for that purpose is to not use git to its full potential.

Stashing things you care about for some later time strikes me as the kind of use of stash that is the most prone to data loss. But again, if you're comfortable using fsck, none of this applies to you.

Re: Lesser known Git commands

#135
post #16

I've seen more stash accidents than any other kind with git. Stashing is more dangerous than committing or branching, and to me it doesn't seem to provide any advantages... do people actually find stashing easier than branching? Is it just because when you branch you have to name it, and that causes friction? I stay away from stash. Right from the man page: "If you mistakenly drop or clear stashes, they cannot be rec…

Honestly I stash only cause I don't fully understand how to branch and bring my changes with me when I realize I should have branched earlier

This is a great answer, honestly, and you're not alone.

FWIW, here's how. Since stash only captures uncommitted changes, I assume you're working on master and want to create a feature branch, and you've already made some changes for the branch.

  git checkout -b myFeature
That's it. Uncommitted changes aren't in a branch yet, so they don't have to be stashed before you make a new one. You can always start a branch from wherever you are, and switch to it, and your changes will be right there. Now you can commit, and your commit will be on the branch myFeature.

BTW, you can switch branches without stashing too. Git will prevent you from messing up your uncommitted changes. If that happens, then you can commit or stash first. The safest course of action is always to commit any changes first before you do anything.

It's also easy to build your feature branch if you have both committed and uncommitted changes already, or if you want to base your feature branch off a different branch than the one you're working in. I'm already spamming you, so just say so if you'd like me to outline those.

Re: Lesser known Git commands

#136
post #135

Earlier quoted context omitted.

Honestly I stash only cause I don't fully understand how to branch and bring my changes with me when I realize I should have branched earlier

This is a great answer, honestly, and you're not alone. FWIW, here's how. Since stash only captures uncommitted changes, I assume you're working on master and want to create a feature branch, and you've already made some changes for the branch. git checkout -b myFeature That's it. Uncommitted changes aren't in a branch yet, so they don't have to be stashed before you make a new one. You can always start a branch from…

Thank you for explaining this! I didn't know that and will start incorporating that into my workflow :) thanks for teaching me something new!

Re: Lesser known Git commands

#137
post #52

Earlier quoted context omitted.

You can already merge two divergent histories with the --allow-unrelated-histories option. (At the data level, merge commits don't care that their parents have a common ancestor, but the git merge command does this as a safety check.) In other words, all repos already are subsets of the ur-repo. The semantically-interesting data in git is not the commits themselves, but the branch names given to specific commits in s…

Interesting, now I learned that a git repo can have any number of commits that have no parents. It can be achieved by fetching an unrelated repo and merging with --allow-unrelated-histories or by using git checkout --orphan. > safety check Why is this considered unsafe? Only to avoid pulling from unrelated repos by accident? The man says for --allow-unrelated histories: > As that is a very rare occasion, no configura…

Yeah, I imagine it's unsafe because "git pull" implicitly creates a merge commit when it can't otherwise update, and your remote URL might now be pointing at a different history. Maybe github.com/someproject/somecode got replaced by a clean rewrite and you're actually looking for someproject/somecode-old. Maybe you were pointing at an unofficial git-svn import and now there's an official git migration. And so forth.

(Personally, I think the right way to address this is for "git pull" not to implicitly create merge commits...)

Re: Lesser known Git commands

#138
post #126

Earlier quoted context omitted.

I am of course aware of git aliases (e.g. because OP uses them a lot) but it never occured to me specifically to shorten git to g and find a way to keep autocomplete working. However, since these are by far my most typed commands (specifically, probably 40% of my executed commands are `s`), I strongly care about the difference even between 1 and 3 keystrokes. Thanks for your feedback. I wonder if the downvote was bec…

I never downvote anything, so I'm not sure, but maybe the use of "advise" and "canon" triggered negative votes?

Thanks (if you're still reading this thread), I didn't know "advise" carried negative connotations. I guess it's one of those words that I learned from a dictionary and never stopped to notice that English speakers use it only in much more formal situations than the word in my native language that I'm trying to evoke.

Should that maybe have been "recommend"?

Re: Lesser known Git commands

#139
post #134

Earlier quoted context omitted.

I frequently swap between branches, for code review, or to move temporarily to something else for a short time. I decide whether to commit what I have done or whether to stash it for now, based on what state it is in. If I am still in the exploratory stage of the work, I usually wont commit, I will just stash and come back to it later. Its a useful thing to be able to do at time when i am not yet ready to COMMIT to t…

Of course I can't tell what your comfort level with git it. The more expert you are, the more it doesn't matter, and you can use stash safely. I am not judging anyone or their workflows. It's the stash command that has the problem, because it circumvents git. That said, my reaction to your comment is that you're taking "commit" too seriously. ;) Nothing in git is a commitment until you push. Nothing. If you haven't h…

If code is important enough to me that I care whether or not I lose it, I commit and push.

I prefer to commit discrete change sets (not features, or stories, just a discrete set of changes that achieve a piece of what I am wanting, dont break the code base and dont break the build).

I have heard that phrase, I live by it and encourage others to do the same. it is especially important when working as a part of a bigger team on the same area of the code.

Teams that commit early and often are happy teams :)

OTOH I use stash constantly, multiple times every day, when switching between branches, because sometimes its just handy to be able to put stuff aside to look at something else.

I dont recall ever losing code because of it, but it is certainly possible and its not hard to see how it could happen.

Re: Lesser known Git commands

#140
post #126

Earlier quoted context omitted.

I never downvote anything, so I'm not sure, but maybe the use of "advise" and "canon" triggered negative votes?

Thanks (if you're still reading this thread), I didn't know "advise" carried negative connotations. I guess it's one of those words that I learned from a dictionary and never stopped to notice that English speakers use it only in much more formal situations than the word in my native language that I'm trying to evoke. Should that maybe have been "recommend"?

English isn't my 1st language either, but the power of downvotes is misused a lot on the internet, especially when there's no public trail who downvoted. Advise and canon may just carry too strong of a meaning for those who grew up in English-speaking school systems.
Post reply on HN