Hacker News new | past | comments | ask | show | jobs | submit login

I think of log, cherry-pick, stash & blame "quarterly use" commands rather than "daily use" commands. log maybe monthly, the rest quarterly unless you're doing something wrong.



> I think of log, cherry-pick, stash & blame "quarterly use" commands

At work we do care that our git history makes sense, is free of random nonsense, but contains only self-contained commits with reasonable documentation. So I call git log many times every day, I would not know how to do it without.

Cherry-pick probably depends how may maintenance branches you maintain. We don't have many, so I don't need it very often. I guess that could be very different for someone required to support long product life cycles. Sometimes when I need to split or unite development branches that need major reorganization I use it.

Blame I need soon when I try to understand others code. Sometimes even on my own. Also when you get bug reports form the field, to understand how long certain bugs existed. Not always to be able to blame the author, but just understanding how long a line has been unchanged.

Personally I don't use stash a lot because I'm not afraid of committing anything to my working branch. I can always fix the code or the history later. Or I make a temporary branch with a descriptive name than just stash. Some use stash more frequently I have noticed.


How can you pull without using stash? Do you always commit everything before pulling?

You also need the log daily to know things like "what changes made it into this build", or almost everytime I fix a merge conflict, to understand why something is the way it is.

I can grant that cherry-pick & blame are more rarely used, though blame is often on by default in many editors, and cherry-pick is something my team does daily around every release (since we don't want to merge the trunk into the release branch the day of the release for 1 bugfix).


I rarely use "git pull". Why would you?

More typically, I will "git fetch origin" to fetch the current integration branches, then "git checkout -b <feature branch> origin/master" to start a new feature branch from a given integration branch, then push that once the change is completed.

If I need to update a local copy of an integration branch, then I might well use "git pull". But I would never have any local changes made there which would require stashing, since all changes are done on feature branches.


I use git pull pretty frequently. I like to keep my main branch up to date with the main branch of the remote repo. I find it's helpful to have that consistency across contexts.

I think diffs are faster if it's to the local repo vs the remote repo.

I always make branches off local-main, as opposed to remote main as in your example.

I think it's also helpful to have the main branch replicated across as many machines as possible. There have been one or two times where a dev has deleted remote main at my company where some (very VERY CALM) git push solved the problem. I probably could have checked out a tracking branch and fixed it that way, but having a local copy of main made it a one-step process (I think the resolution was just to git push the main branch?).


There are few differences between "local" and "remote" main in GP's example. "origin/master" is a _local_ copy of the origin's master branch, and updated with every "git fetch". So "git push origin origin/master:master" resolves the "remote master was deleted" without having to stash/checkout/etc.


It's just a preference thing. If I'm sitting down to write a new feature I can do the git fetch origin and go directly to a branch, but if I'm investigating an issue, I'll often open that develop/master branch directly, find the problem, do a pull to make sure there are no changes that got checked in, then "git checkout -b".

Alternately if I'm helping other developers, I'm on their branch a lot, and it basically becomes a "push your changes and I'll take a look" and I just open that folder and git pull.

I think I use more git pull now than I did originally, because I'm working on less of my own code.


I basically never use git pull. I use git fetch and then I check (using git diff, git log or in confusing cases gitk) what I want to do. That could be merge (fast forward), rebase, ignore or either branch because the other one is just better. Of course often pull might do what you want, but when it doesn't people start to complain. So better avoiding surprises from the beginning.


It sounds like you finish your work much faster than I do. I usually go for the same workflow as you do, but it can take days between a branch being created and the moment I'm done with it. During this time, I often want to keep up with the latest changes on master. Other times, more than one person works on a feature branch, so they still need to git pull from origin/feature-branch into feature-branch to get the changes from the other committer.

I would be very happy if I could just merge to master every day, but that is extremely rare for me and my team.


No, I don't necessarily work any faster. But I will switch between multiple feature branches as necessary. And to keep up with master, I'll rebase my feature branch onto origin/master or depending upon the circumstance I'll directly merge origin/master. Both keep me up-to-date without a direct pull.


Well, if you're switching branches, you already have problems with a dirty worktree. Also, pulling can actually mean rebasing (I always use pull --rebase).


I've worked at a few places where CI will automatically merge main back into open feature branches (or at least open PRs). It's quite nice.


My team works on feature branches that get merged to master. Only master ever needs a git pull and you never work directly on master. Every team I've worked with over the last ten years has done some version of this work flow with small deviations.

Your uses for log sound legitimate but usually they are resolved over other communication channels (in person or over slack or in release notes) on the teams I've worked on.


I almost never use `git pull`. I have a helper script (written by an ex-coworker's father ...) that fetches + updates my master branch head to the proper place, without changing away from my current branch.

If I want to have things-from-master in my current branch, I either rebase my branch onto master or merge master into my branch. (I'm lucky that my branches are short-lived enough that rebasing on top of master is almost always easy and the right choice.) If I have unfinished things, I'll make a "WIP" commit, that I will unroll later after doing the rebase.

I nearly never use `git blame` on the command line, but have a very frequently used hotkey bound to it in my editor to show the blame annotations.


It sounds like you're using a very different and much more complex process than average. Keep in mind for a lot of web projects releases are every day, sometimes multiple times per day.

If you take out the concept of builds, you just have short lived feature branches off of master, you're left with perhaps even less than the 8 commands listed above.


For our project, a flow like `create feature branch -> implement -> push -> review -> merge to master` is rarely something that finishes every day (but there are daily changes to master from someone else on the team). Builds are something that happens for every change to master, and there is constant QA on those builds. Even if we chose to release those builds to customers, the question of "did a fix for bug X make it into build Y" would still arise quite often.


I feel like the response is why wouldn't you use a separate branch for your feature/changes?


Yes. Doing a “git commit -am savepoint” on a feature branch is not a big deal; it will get folded into the squash merge with everything else in that unit of code review.


`git pull --rebase` ?


If you have a dirty worktree, `git pull --rebase` fails. You need to either commit or stash your local changes. To stash them, you can use git stash. If you decide to commit them, that's ok, but then you also need to learn about `git reset --hard` or `git commit --amend` or `git push --squash` if the changes were work-in-progress.

So which would you recommend?

Oh, there is also the option of enabling autostash I think, but that is relatively recent (maybe 1 year?)


If you have to pull while your work tree is dirty, it’s best but not easiest to branch & commit (safest and avoids the possibility of conflicts during pull), or commit & pull with rebase (safe but might have conflicts).

In case you weren’t aware, stash is not as safe as other git commands, it doesn’t have the same safety net and reflog support as a commit does. It’s relatively easy to drop stashes accidentally and lose them forever. I’ve seen people do this in production by not being careful when pulling while they have a dirty work tree. The man page for git stash mentions this fact:

“If you mistakenly drop or clear stash entries, they cannot be recovered through the normal safety mechanisms. However, you can try the following incantation to get a list of stash entries that are still in your repository, but not reachable any more:

    git fsck --unreachable |
    grep commit | cut -d\  -f3 |
    xargs git log --merges --no-walk --grep=WIP

https://git-scm.com/docs/git-stash


It's interesting that you mention branching, because that is another workflow where I feel that I constantly have to reach for stashing - when I simply want to move to another branch (either for a quick bugfix or simply to check something).

Otherwise yes, I know you can relatively easily lose work with git stash (I actually once lost about 2-4 days of work with a P4 shelve, which is an extremely similar feature), but it still seems easier to me than committing and then cleaning up history/resetting if you change your mind about the implementation...


It might be worth really picking apart why you think you need to stash instead of commit, and why stash feels easier. I honestly don’t think committing is any more work than stashing at all, not even more typing. It’s really not more difficult to commit what you have temporarily, go to another branch to work, then come back and continue working, compared to stash. But I don’t doubt that it feels more difficult for some reason. Is it the need to make a commit message that causes the mental friction? Does git reset somehow seem tricker than git stash pop? Think about how you typically rebase when you’re done anyway, so that means when you come back to a branch with a temporary commit, you don’t have to stash pop, you can just add more changes and squash or rebase it all later. With the stash workflow you have to keep the stashes in your head, and manually pop them. They get harder to manage than branches when you have multiple stashes, since they’re disconnected from their context. Personally I think if you examine what it really takes to use commits & branches, and practice using them more, you may find it’s just as easy as the stash workflow, if not easier, and it comes with a wider safety net and is easier to manage when you have a lot of different changes in flight at once. I also think it helps to realize that a branch is nothing more than a named SHA, they are incredibly lightweight, and using them ought to reflect that.


I think it's primarily a question of focus: I want to pull or to switch a branch. The fact that I have to do something like committing or stashing is already an annoyance - having to come up with a commit message is even worse.

Perhaps I will give this commit/reset workflow a try as well, to see how it feels. It may also be that committing still feels to much like "an event" for me, from my P4 days.


You can, if you want, git fetch without committing or stashing, and then checkout just the files you want to update in your work tree, as long as they’re not the files you’re working on.

Aside from that, I hear you, git’s model is fundamentally different from Perforce. There’s no choice about whether you need a clean work tree before pulling, that’s simply a git requirement. So the main thing to ask now is what workflow you want and what safety net you want underneath it. On one side, the best way to focus is to not pull anything while you’re working and have a dirty work tree. But things come up at work, that’s not always realistic, so the next question is how to make the workflow both safe and also instinctual so that it doesn’t have friction.

I do think there’s something to your notion that commit feels more serious and heavy than stash, and that is something I personally have tried to break down. In git, commits and branches can be so much more lightweight, fluid and flexible, but it takes practice and fluency in git to be able to actually feel that.

It might be worth considering some shell or git aliases to do common things. You could easily alias a command that commits your work in progress with a comment “WIP”, and never have to type it. You can do the same with a branch and even keep around a branch for work in progress that is always temporary and gets force reset to whatever you’re working on. (Remember a branch is just a pointer and nothing more, you can completely change what it points to without hurting anything, and the change is stored in the reflog, so there’s a undo button.) I think it is possible to make a branch & commit workflow that is both easier and safer than stash.


commit soon, commit often, work in a dev branch and rebase -i to squash, amend, edit anything you want before pushing


Well, you get rid of the need to know git stash, but now you need rebase -i, amend, the idea of squashing, probably git reset if you're not happy with a commit... Whichever way you look at it, you need to learn quite a few more commands (and concepts!) than what the initial list claimed.


Cherry-pick probably depends on what kind of software you're working on. If there is alway exactly one version in production (two if you deploy gradually), then I don't see it being needed often. If you are supporting multiple versions at once, then it ends up getting used just about every time you have to fix a bug.


We also use it very often when we approach a release - usually there is a release branch that gets cut from master, and then for a while you have in parallel features going to master and bugfixes going to master and cherry-picked to release.


How funny, i use log multiple times a day. But i also stash things in my commit, per branch, and cleanup later. /shrug


cherry-pick is frequently used if you have maintenance branches that need changes from master.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: