7 ms·
I support this fully. Juniors and intermediate engineers I work with still struggle with git quite often and I personally know how that feels firsthand. Not su
by cupofjoakim 3y ago
I support this fully. Juniors and intermediate engineers I work with still struggle with git quite often and I personally know how that feels firsthand.
Not sure if this solves the issue. I personally recommend using git, but keeping it simple by limiting the allowed operations.
- git switch
- git checkout
- git add
- git commit
- git pull
- git push
- git rebase
- git reset
Note the absence of merge and and cherry pick. Most often when a junior has messed something up it seems to be because of merging in a weird order or cherry picking the wrong thing before merging or rebasing.
Either my juniors have stopped asking me for advice (totally possible) or this recommendation helps. As I find myself very seldom needing those commands I hope and believe it's the latter :)
- kingdomforgit 3y agoI agree mostly but recommend avoiding rebase at all costs at all times always and always prefer merge. Rebase is pure evil plain and simple.
- computerfriend 3y agoI rebase constantly and I love it. To each their own, I guess.
- tylerscott 3y agoI do as well and I also cherry pick a lot specifically with —no-commit to pull together disparate ideas from various sources. I am always fascinated when git usage comes up in threads because there are so many ways people use it that differ from my own and we all seem to find value in it!
- okeuro49 3y agoI use rebase to roll up all my commits before submitting a PR. Don't see what the big deal is.
- quesera 3y agoThat's the simple and safe use of rebase. Rolling up your local wip commits into a coherent story of one or a few clearer commits. The more-complicated but still safe use is to rebase your local branch on top of an advanced upstream before pushing. Some people prefer merge for this case, but it is somewhat impure. The problematic use of rebase is on pushed branches. Especially if you have collaborators.
- SAI_Peregrinus 3y ago> The problematic use of rebase is on pushed branches. Especially if you have collaborators. Yep. As soon as you have a PR out, and have to address comments, you have a public branch and can't safely rebase it. So you can't roll those new changes in to the "clean" history, If upstream also has changes before your PR gets merged, you'll also have to add a merge commit anyway.
- morelisp 3y agoThis is a problem of GitHub, not Git. E.g. GitLab preserves comments as well across rebases as any commit changes. "Don't rebase public branches" is an easy way to say "if someone has built something on top your branch, don't rebase unless you expect them to also rebase." 90% of the time this is not actually harder than merging, though, and still produces a better history and more atomic commits. At this point I'm even only 99% firm on "never rebase master", as long as release tags are truly immutable.
- l72 3y agoThe rebase crowd seems to be obsessed with it due to wanting linear history. In my opinion, the reason for all of this is due to how `git log` shows history. If you merge a branch, then every commit in the branch is now scattered among your mainline history, making it confusing to see what is going on. So, instead of fixing `git log`, you end up rebaseing (and possibly squashing) on top of the main branch, then doing a fast forward commit so you get a "clean, linear history". But, if git just change the default of `git log` to `git log --first-parent`, then so much of this would go away. Only top level commits (directly to the branch, fast-forward merged, or a merge commit) show up in the history. Now, let's say I have a branch that I've been working on for 2 weeks. I have 20+ commits. During that time, I've already needed to merge the main branch into my branch to keep it up to date several times. I can either rebase the whole thing, to clean up history, remove the merge commits from main, squash unnecessary changes, and so on, just so I can get a "clean" history in main, or, we can just do a merge commit bringing in my whole branch with a good commit message. I prefer the merge commit because it is then very easy to track _all_ of the changes made in my branch by a single commit. I can do a diff on the merge commit and see all changes. I can cherry-pick just the merge commit and bring in all the changes. If I need to break down what the original developer of the branch was doing, I can walk through all the sub-commits. There is no need for them to rewrite history and hide their workflow or their process. But again, the problem is, by default, `git log` shows this as a huge mess, whereas `git log --first-parent` would _only_ show the merge commit, and would hide all the child commits that happened in the branch. After all, the top level merge commit is what is important, we only care about the subcommits when we need to dig in.
- hedora 3y agoMerge breaks your history. Most people start where you are, then eventually realize that merge is actually non-understandable, and switch to rebase. Hint: “git rebase -i HEAD~3” is your friend. So is “git bisect”.
- kingdomforgit 3y ago> Most people start where you are I've used almost every source control system known to humans the past several decades and git for over a decade. I've heard the git rebase preachers. I tried to get onboard with rebase. All who read, avoid rebase at all costs at all times, always.
- mixmastamyk 3y agoA bit overstated but yes. Merge squash works every time. Rebase in my experience at work led to inexplicable conflicts several times I tried. When that happens the rebase preachers will be nowhere to be found, and you’re on your own.
- avgcorrection 3y ago> Merge squash works every time. Which is a particular kind of rebase except the final commit gets cherry-picked to the target branch (instead of rewriting the original branch).
- turtles3 3y ago> Merge squash works every time. Unless you've already started a follow-up branch before the first gets merged (eg. Waiting for QA, PO review etc.) Then you at minimum will need to rebase your second branch after the first is merged. Not a disaster but it adds overhead.
- mixmastamyk 3y agoNever did that exactly. Think I've either, started a new branch from the waiting one or, started a new branch from the main and then pulled from the older feature branch. Have no recollection of any problems, but it is rare enough to not have tried it recently.
- quesera 3y agoI use git merge a lot (others might too, perhaps only via the Git(Hu|La)b interface though?). I use git cherry-pick very occasionally. I agree it's probably a mistake in most cases, but there are valid heavily constrained circumstances where it's fine. I had never heard of git switch. It looks like just another git checkout?
- bombcar 3y agocheckout is an older command and does more switch just does what people think checkout does. https://linuxhandbook.com/git-switch-checkout/amp/ https://linuxhandbook.com/git-switch-checkout/amp/
- ozim 3y agoFor me most people should not cherry pick-revert-merge-rebase. They should create branch of development/trunk do commits with their work and create PR. Then PR merge in GitHub interface or something. 98% done other 2% get some git specialists.
- yCombLinks 3y agoThat means on average your project must have 50 users to have 1 git specialist. Git problems however seem to happen far more than for 1 in 50 developers I've worked with.
- golergka 3y agoRewriting history with rebase is a destructive operation and I would never advocate for it to juniors. Merges are much more straightforward because they follow the git mental model of acyclical directed graph.
- darekkay 3y ago> Rewriting history with rebase is a destructive operation. It's not, because Git history is immutable [0], you can't change it. But I understand that from the user perspective it appears to change, and the consequences for public history "changes" have to be known to prevent any troubles. [0] https://darekkay.com/blog/git-rewriting-history/ https://darekkay.com/blog/git-rewriting-history/
- epcoa 3y ago> It's not, because Git history is immutable [0], you can't change it. > It is by design impossible to modify or delete an existing commit with regular Git commands. These are both just straight up incorrect. Make the commit unreachable from all regular branches (this can be as simple as a reset or rebase - and at this point is effectively rewriting history), then gc. Oh, ah you say, there’s a reflog. But that can be pruned/expired with the very same regular reflog command you refer to in your post (or just change the unreachable expiry from 30 days to now). At that point the commit is truly unreachable and a gc will make it go away forever. FYI the commands git reflog expire --expire=now --all && git gc --prune=now should do the trick about truly deleting commit objects for good. Also the filter commands allow rewriting history. This makes a difference because your wording implies that there is some inherent structural invariant that makes git history immutable - and there certainly isn’t, there’s just some default policy for how otherwise unreachable objects are recoverable. Also I think when most people say (correctly [0]) that git history is mutable it is that by default it is easy to rewrite the history of any branch and basically manipulate the commit graph in any way, and all can be done with the standard command line tools. Bringing in the reflog is mostly irrelevant to the concept of history rewriting. > But I understand that from the user perspective it appears to change If you force push to a shared repo, there's no "perspective" about it - the history has changed, somebody else may basically get a completely unrelated graph to what they have in their own repo. Bottom line: The person you're replying to is correct, rebase is a fundamentally destructive operation, because while the objects in git are immutable the references are not and that's all that matters - because a commit without a reference might as well not exist, it's not a history, it's just a commit. Starting with rebase you can prove to yourself that you can make the repo dispose of commit, tree and blob objects forever. I see the distinction that you are trying to make but I don't see why it is either pedagogically or practically a useful one. [0] https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History (no scare quotes needed)
- devjab 3y agoI support it, but I also wonder why other teams seem to spend so much time on git than we do. Our setup is fairly basic, you have a main branch, you can only push things too it by squash merge pull request that are linked to a work item, and you can only do so after whatever you’ve build has gone through the release pipeline, which among other things involve spinning up an instance of it for POs or whatever to test. When a dev wants to change something, they pick a work item on our “mostly kanban” board, and create a branch from there with a dev/name. Behind the scenes this spins up a build and a deployment to a dev/name deployment slot whenever something is pushed to it. They do their things, other devs do theirs, similarly on dev/othername branches and then when whatever is complete it gets squash merged into the main branch with a direct link to the kanban work item. You’re mostly free to do what you want on your dev/name branch. The only thing you really need to teach “juniors” is that they will hate themselves unless they merge main into their dev branches regularly. But if you’re heading home and want to commit something, or you simply commit as often as you click cmd+s, you can do it with no useful comment because it’ll get squashed anyway. Most people where I work use GitKraken, mostly out of habit, but I think more and more are switching to VSC extensions and some might even use the cli. The result is that we spend almost 0 time on “git” in our organisation. I wonder if we do things wrong somehow since git seems to cause issues for so many people.
- mixmastamyk 3y agoSame, devs overthink it. Others obsess over history, but personally didn’t find it worth the effort. We look back maybe twice a year, typically fixing issues moving forward.
- devjab 3y agoI guess it does depend on the size of your commits. Ours being relatively small (one work item) we still have the history, while devs getting the freedom to not have to make every commit meaningful.
- sureglymop 3y agoWhat's helped me much more lately is undotree for vim [1]. It basically logs every single time a file is saved. Its much more useful because commits have to be made by humans and they may not do it often (and usually there is an incentive for "clean or working commits"). There have been many times where I went back to copy something from the undotree. [1]: https://github.com/mbbill/undotree https://github.com/mbbill/undotree
- letmeinhere 3y agoshould use `git restore` alongside `git switch`, right?
- metaltyphoon 3y agoAnd git add —p
- pwdisswordfishc 3y agofatal: pathspec '—p' did not match any files
- metaltyphoon 3y agoLol, it was 1 dash