20 ms·
Idiot Proof Git
- teo_zero 4y agoGit's interface is like the 'find' UNIX command: it makes complex things possible, but does nothing to make common ones easy. 99% of times I want to find a file in the current directory or below: find . -name foo -print Can you spot the 3 obvious arguments that find shouldn't require me to type? Similarly, if so many users add -a to their git commands, why is this relegated to such an ugly flag?
- throwaw20221107 4y agoYa, the three arguments are 1. `|` 2. `grep` 3. `"my actual filter"`
- expazl 4y agoGenuine question. What makes you feel that -a is an ugly flag?
- teo_zero 4y agoFlags are modifiers to alter the standard behavior of a command. If you use it 99% of the times, then I'll argue that the definition of "standard" is wrong.
- chociej 4y agoTBF (at least with GNU find) you don't have to: find -name foo
- throwaw20221107 4y agoModern Git workflow is very simple on its own: 1. Your codebase has a `main` branch which is write-protected 2. Devs submit changes to `main` from their own branches using PRs 3. Devs can do whatever the fuck they want on their own branch 4. PRs are merged one at a time 5. When merge happens a dev's PR is squashed into one commit that gets appended to `main` 6. If next dev wants to merge their PR with a conflicting change they have to resolve the conflict first and then they merge 7. The end result is that `main` is a linear history of all PRs with the time they were committed to the `main` branch i.e., when they could've started to break prod. This is a solved problem and it works great in industry. Why break it? If you want interactive rebase then make 2 PRs.
- deleted 4y ago[deleted]
- xenomachina 4y agoI 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 reason about. The "first parent" of each commit on the main branch is a linear chain of the main branch history. However, for more complex changes you don't have to squash. Those intermediate commits will be on the second parent of merges, so they're easy to filter out: M─┐ [main] merge │ o commit M─┤ merge │ o commit M─┤ merge │ o commit │ o commit M─┤ merge │ o commit > If you want interactive rebase then make 2 PRs. What do you mean?
- throwaw20221107 4y agoWhat 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."
- chociej 4y agoIt's reasonable to want a series of commits (or patches) to be pulled together, assuming they are well-organized commits.
- P5fRxh5kUvp2th 4y agoIt's flat out amazing how often people want to complicate git. My current company, everyone is in love with git flow. I pointed out the person who originally created it literally wrote a blog post explaining why it was designed for very specific needs that most projects don't have, and yet ... I constantly see people doing presentations on how this is all supposed to work. And why? You can get away with very simple flows.
- est 4y agoIMHO 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.
- rapind 4y ago> 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.
- zenogantner 4y agoBeing able to undo an action is is actually a general usability principle that has been around at least since the 1980s :-).
- forgotpwd16 4y agoThe Humane Interface, a book on UIs by J. Raskin, talks about the importance of undo/redo.
- rapind 4y agoFair enough, I should have been clearer. I’m thinking about extending it to CRUD apps for example. I haven’t personally seen any do that, and it might get really involved due to dependencies, integrations, etc.
- stephen_g 4y agoThat'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.
- fortran77 4y agoI find most attempts to hide how git really works with alternate commands just end up biting when something unexpected happens.
- beezlewax 4y agoI feel like the fact that we have these incessant conversations about how to use git just show that the interface is inherently broken. New programmers always struggle with git. The naming of the commands is bizarre and confusing. The docs are overbearing and a lot of the time the fact that it's powerful in weird edge cases is seen to trump all of its flaws. That said I haven't seen anything better or even close to its usefulness. Lack of any real competition may be an issue there.
- buck4roo 4y agoMy solution: use mercurial. Works with git repos (w/hg-git extension). Designed for humans. Sanity provoking. Gets out of your way, as a good SCM tool should.
- danpalmer 4y agoBig fan of Git style guides in teams. We had one at Thread. It was common for engineers to come in and find we didn't do rebasing and find it weird, but we took the opinion that history should be exactly what you actually did, not some clean and idealised version of what you wish you had done. There are advantages and disadvantages to this, but having a defined approach was the most important aspect. Also the fact that we didn't rebase and used merges everywhere was a major contributor to no one ever breaking their git repos, something that git seems notorious for elsewhere.
- throwawaylinux 4y ago> that history should be exactly what you actually did That gives you the history of exactly what git commits you made, not exactly what you did and how you went about solving the problem though, right? git describes changes to the source. It seems like you're getting the worst of both worlds, trying to understand how the source changed is much harder when you have peoples' experiments and draft changes and false starts littering the history. And understanding the approach to problem solving and why decisions were made is pretty unsatisfying by digging through that stuff too really. That seems better kept as documentation and/or in the commit logs.
- Shorel 4y agoFor me, there should be a balance between the detail of history and the usefulness of the information. For the changes I do, not only I rebase them all in a single commit, I don't even merge branches. I cherry-pick my changeset. Clean commits, clean history. Whatever I do before a push is my business and no one's else. For anyone else changes, that's it, anyone who is not me: history is untouchable. No rebases, no squash, whatever it is already pushed, must stay as it is. When I do a pull: git stash, git pull --rebase, git stash pop I encourage everyone to clean their commits before a push. A clean history is a good history.
- tyingq 4y agoWhat about squashing commits in a merge? I don't do that all the time, but it is useful for certain things. Like repeated code changes to test something in the CI/CD pipeline (that I can't replicate well locally), where only the last change that got it working is of any interest.
- ilovecaching 4y agoRebase (non-local rebase) based workflows are just awful. The best git methodology I've seen is (surprise, surprise) in the Linux kernel. I can keep everyones tree as a separate tracking branch and use git work trees to develop against multiple branches on the same system. I also really enjoy using git request-pull, send-email, etc. and I think Github has been actively harmful in teaching people bad git habits.
- sigmonsays 4y agoany pointers on where to start for request-pull, send-email, etc. Ie, the linux kernel flow? Everything is a PR these days in github, so perhaps we find a way to do this with github.
- account42 4y agoRebasing remote feature branches after feedback in the github-pull-request workflow is analogous to re-sending and updated patch series in the email workflow. The distinction shouldn't be if its remote or not but if its something "published" that others might build their work upon.
- distcs 4y agoHow is push origin HEAD --force-with-lease different from normal git push? Can someone please explain this to me?
- ok_dad 4y agoIt will overwrite the tree on remote as long as remote hasn't changed since you last fetched it. Like --force, but can help to prevent overwriting other people's changes when they push in between you fetching. It doesn't always work, particularly if you have a tool which continuously fetches remote, like an IDE configured to do so such as VSCode. In that case, you will have fetched the other person's changes, and --force-with-lease will happily blow-away anything on remote that might not be in your tree yet.
- FPGAhacker 4y agoOof, thanks for that warning. So it will blow away changes you haven’t merged (only fetched)? I guess git can’t tell the he difference between “not merged yet” and “don’t want to merge, please destroy”
- erik_seaberg 4y agoThe changes still exist in the repo’s reflog (for 30 days by default), but they might not be reachable from the ref’s new tip commit.
- rawling 4y agoIf you don't want to blow away changes you haven't merged, you shouldn't be doing force at all?
- FPGAhacker 4y agoWell, the article presents a seemingly nice workflow that lets you handle local rebases. I was considering it. However, we use vscode, and I rather like auto fetch. But apparently this workflow would destroy something auto fetched that I might not have even noticed.
- thesuitonym 4y agoI'm reminded of the saying, "if you make something idiot proof, someone will make a better idiot."
- softwaredoug 4y agoAs I get older, I become the next dumber idiot :D
- wruza 4y agoThis is misleading. There are all sorts of "idiots" on a bell curve already and making something easier simply widens the stripe of effectiveness. It is a good thing because you now have more "idiots" who could do the job just fine.
- opsy_ 4y agoI think the implication is often efforts towards "idiot proofing" don't actually improve effectiveness at the end of the day. They simply add something else to trip on. I'd roughly say that's the case with OPs aliases. Useful if you know what you're doing, or maybe would work with a strict team policy. Otherwise are just going to create more trouble (especially with that force pushing bit in there...). ETA: I fully support usability! "real programmers just read the manual" arguments be damned.
- daneel_w 4y agoI'm incredibly thankful that 99% of my Git usage at work gets away with just PULL, CHECKOUT [-b], COMMIT [--amend] and PUSH. Rarely do I need to rebase, for any reason.
- Shacklz 4y agoI 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 metadata) to a tree, a tree is just... and so on. 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. Anyway, not trying to convince you or anything, just saying that I've been in your place a few years back, and wish I'd realized earlier how easy it actually is.
- Dylan16807 4y ago> 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 didn't help. It would have been easier to copy all the source files out, check out the branch I wanted, then copy them all back in.
- Shacklz 4y ago> 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.
- ok_dad 4y ago--force-with-lease can be a footgun. It will overwrite the tree on remote as long as remote hasn't changed since you last fetched it. It doesn't always work, particularly if you have a tool which continuously fetches remote, like an IDE configured to do so such as VSCode. In that case, you will have fetched the other person's changes, and --force-with-lease will happily blow-away anything on remote that might not be in your tree yet.
- eru 4y agoYes, but it's still better than --force under most circumstances.
- blowski 4y agoWhy use force at all, on a default command?
- skrtskrt 4y agomy flow is (on my-branch with no one else's commits) * push some commits up to my remote branch * git fetch * git rebase master/main to get the latest stuff * add changes on my-branch that use new stuff from master/main * git push --force-with-lease to my remote branch - this fails if you don't use some version of force since my most recent commit is based on a commit (from master) not on the remote branch
- G3rn0ti 4y agoI don’t get why everybody wants to rebase their topic branches. Just use merge, come on. If you want a „clean“ commit history on main/master do a squashed merge into main at the end. This way we never had to force anything on the remote.
- ok_dad 4y agoI rebase on my topic branches because then my edits are neatly stacked on top of the other branch, so I can re-arrange things more easily. Why would I want a weird commit with a bunch of work I didn't do on the topic just smooshed into the middle of my well-crafted series of commits?
- fedeb95 4y agoThis can be fine in two scenarios: - solo dev - enforcing its use in your company Otherwise big messes will inevitably arise. In the second case, new people with their (correct) git workflow will suffer.
- andrewvc 4y agoRebase should never be used. Or, if it is used, it should be treated as a dangerous thing to do that’s well outside the norm. Most of the arguments in favor of rebase are by people fanatical about having a git history organized just so. It’s not worth the headache and effort. PRs are a better unit of work than commits in practice. Configure GitHub or whatever you use to squash merge only and you’ll be good. Since moving to this workflow I’ve had zero issues losing data due to a confusing git situation.
- chociej 4y agoIf having a nice history isn't important, and if PRs are a better unit than commits, why squash?
- ltbarcly3 4y ago
- account42 4y agoThat's because they know how to use git so that they don't have to pick a child when they bisect.
- ltbarcly3 4y agoMy point on my now flagged and dead?? post was that people think git history is linear, so they believe they have to do special stuff so it's a 'good' linear history when this is pointless.
- TeMPOraL 4y agoI use rebase, for two reasons: 1. (major): it lets me commit at my pace, and then publish my work at the pace the team prefers (which is a combination of what the team wants and what won't choke the CI, but that's a story for another time). The ratio of my local commits to commits sent to code review is often 5-10:1. 2. (minor): because I hate to see a Git history that's over 50% made of "Merged X, Y into develop". It's pure noise. I guess there's probably a command line flag to filter them out, though.
- a3w 4y agoSo, like easy git (egit), but even more minimalistic?
- ltbarcly3 4y agoDon't use this, just learn how git works. Bookmark this page and refer to the commands in the aliases if that helps. These commands are quite opinionated and as likely to cause you to do something you didn't mean to do, possibly destructively, as they are to help. What happens when you have a million conflicts trying to rebase and you need to give up? You need to know how to abort a failed rebase or merge. You shouldn't insist on using a tool if you refuse to learn the basics of using it.
- wruza 4y agoYou need to know how to abort a failed rebase or merge g abort a failed rebase or merge?
- Shadowed_ 4y agoNothing is idiot proof. Only more or less idiot resistant.
- stblack 4y agoI might be mistaken but this post is basically describing git-friendly which I've used for years, is 100% flawless, and you'd need to pry from my cold, dead hands. https://github.com/git-friendly/git-friendly https://github.com/git-friendly/git-friendly
- jaimehrubiks 4y agoOP's post describe the exact command git would use, and explains why, which is great for learning purposes as well.
- ccity88 4y agoI know HN will absolutely tear me apart for recommending this, but I use GitHub desktop. It has all the bells and whistles of the CLI, but you can actually see and understand what's going on. As a Junior Engineer, a Senior Engineer recommended it to me. I thought he was joking at first, but he kindly reminded me that using a GUI app is completely fine and okay. We shouldn't stigmatise tools that make it easier to use and understand your workflow. GitHub desktop allows me to see what i'm committing, commit history and much more. I'd definitely recommend it. PS. Using it is not an excuse not to learn how to use the CLI. Others will accuse me of being lazy and not learning best practice. Learn both. Use the easier one.
- jamisonbryant 4y ago> Learn both. Use the easier one. This is a great point that I will be sharing with my team. Sometimes (most of the time) I use the git cli, and sometimes I use the built-in Git pane in VS Code. I have not used GitHub Desktop in quite a while. In your opinion does it make the commit graph easy-to-read? Because I have not found a tool _yet_ that makes that diagram easily parseable by the human eye. It just looks like a mountain of spaghetti commits linked together with a myriad of colored lines. (I realize that part of the cause of my confusion is crappy discipline around commit history, but what can you do on a team of a certain size where you're not the lead? Just have to suck it up.)
- 4y ago
- agentwiggles 4y agoI guess this will come off kinda... douchey? But I just don't find Git to be that hard. I know there's a lot of complexity there, but I find that 95% of the time I'm just git add -p or git add . and then committing. Every once in a while I'll do a rebase, and that's the most complex part of Git that I use with any frequency. I remember when I first was introduced to Git I found it confusing, so I'm sympathetic to newbies who have to cross over the learning curve, but I think the main day-to-day Git operations just aren't that much to learn. What is it about Git that people find so difficult, even after using it for a while?
- squeaky-clean 4y ago95% of hit usage is fairly easy, yeah. But that other 5% can be extremely difficult.
- randomsearch 4y agoThe UI is inconsistent and unintuitive.
- eru 4y agoThat's true. But they are working on this. Slowly. Eg compare https://git-scm.com/docs/git-switch https://git-scm.com/docs/git-switch to git checkout. https://www.infoq.com/news/2019/08/git-2-23-switch-restore/ https://www.infoq.com/news/2019/08/git-2-23-switch-restore/
- agentwiggles 4y agoI won't disagree with that, but idk. Once you understand the basic operations everything weird is a Google away. I'll admit that Git is the only VCS I've spent any time with, so maybe I just don't know how much better it could be. But I've almost never had an issue with Git where I actually lost code. And anytime I'm doing something dangerous, I just make a backup copy of the directory in case I screw up irrevocably. But even if I'm doing something nasty, the reflog is there, and the cases where I've need to use my backup copy are very few and far between.
- js2 4y ago[deleted]
- wruza 4y agoDoesn't happen ime. I understand how it works (more or less) and still struggle with its CLI. It was created by aliens with photographic memory and non-associative thinking. Maybe you can point to a git test/quiz that doesn't ask stupid trivialities 9 times out of 10? In case I have to "understand" it more, would be nice to pass some informal certification at least.
- alexb_ 4y agoWhat's the deal with squashing commits anyways? I'm genuinely asking, because I've only worked with "squash everything before you put it up for review" but have never really figured out why past "it's what we've always done".
- softwaredoug 4y agoI think people will have a branch with like 40 dumb commits like "fix typo" but when you merge it, people don't want to go through all those 40 commits in main. They want to instead read "Refactored frob reactor to use glom framework".
- planede 4y agomerge commit with git log --first-parent is alright.
- fs111 4y agofix typo yet another typo test fix aaah, why is this test failing? merge foobar/narf revert foo foo Is just not a good history to preserve
- vultour 4y agoBoggles my mind how so many people in this thread are against rebasing. Have they never needed to remove these commits? I do that pretty much daily, especially when troubleshooting something in a CI pipeline.
- Zitrax 4y agoI prefer rebasing too, but merging doesn't mean that you have to merge in all noisy minor fixups, you can combine the strategies and rebase the feature branch into a set of sensible commits, then merge that branch. Preferably even with a CI that checks each commit before merge such that it will not cause issues later during eventual bisections. --fixup and --autosquash are handy for such workflows.
- huimang 4y agoThe problem with git is hardly anyone reads the fucking manual. Git is not hard. The UI is inconsistent, but documented. When you just foist commands onto people, you can't be surprised when they fall off the happy path and don't have the mental model to understand how to fix it. There's no such thing as "idiot-proofing" for people who don't RTFM. --force-with-lease as a default is a really bad idea. Copying random aliases is a bad idea.
- mmmmmbop 4y agoIf one user uses a tool wrong, the user may be at fault. If many users are using a tool wrong, the tool probably doesn't have great UX. Saying "the tool is great, users just need to RTFM" sounds an awful lot like "you're holding it wrong".
- huimang 4y agoIndustry-specific tooling is different than a consumer product explicitly marketed as "intuitive". This comparison doesn't hold, for me. While I agree that git's UI could be made less cumbersome in some cases, many people in this industry want to use sophisticated tooling without doing due diligence such as reading a manual. Handling code versioning in a distributed manner is not an easy task! I don't expect much from junior developers, but if I have to fix trivial git problems from more "senior" developers, I will have some disdain for them.
- weaksauce 4y agoI disagree... git has a fundamental complexity that you can't improve that much on the command line and still have the flexibility and power that it has. I use magit that makes those options a hell of a lot more palatable than they would be on the command line while still affording all the power that you want from pure git. The git-cli has to do everything and there is a fundamental nature of that. I do agree that there are some things that could have been made better with hindsight but that's any project.
- Arelius 4y ago
- gabrielgio 4y agoI like those aliases if you are doing for yourself, but I dislike for beginner (to git) using them to make git "easier". Git UX is confusing and has growing pains I won't deny it, but git is widely used and imho one should take some time to at least understand the basics. I dislike even more the default of many IDE and some git server, they seem to push for the worse git habits.
- wodenokoto 4y agoPretty cool idea. Something I really want is a version of `git amend` that takes a commit hash, so I can amend my changes to any commit, not just the last one without having to start an interactive rebase.
- Zitrax 4y agoYou could create an alias doing something like a "git commit --fixup <sha1>" and then a "git rebase --autosquash <sha1>~".
- firesloth 4y agoI mentioned elsewhere, but I made a simple bash function that does something like that but matches a string in a previous commit message (because I found that easier to type quickly than a commit hash): function git-commit-fixup() { git commit --fixup ":/$*" } # usage: suppose there's a commit "fix: the thing" git-commit-fixup thing # now there's a new commit "fixup! fix: the thing" which can be autosquashed
- deleted 4y ago[deleted]
- lifeisstillgood 4y agobut we have such inventive idiots ...
- jarek83 4y agoWhy use risky rebase while you can just squash all into one commit and push it via intermediate branch (something that Github does as an option)? I prefer to be worry free than always be ready for someone screwing up a branch.
- anonuser123456 4y agoWhy do you feel rebase is risky?
- Arelius 4y agoTo be fair, squash is a form of rebase.
- Joel_Mckay 4y agoNothing is idiot proof, as people greatly underestimate the destructive power of a motivated idiot. =)
- krossitalk 4y agoJust learn Git. It's really not that bad. Don't _ever_ make someone use Rebase without their understanding of what that really means.
- wyclif 4y agoIt is worth the investment to learn advanced Git if you're a software engineer. Start by reading the Chacon book cover to cover. It is a major tool you use every work day, so it's important to understand it.
- Someone1234 4y agoGit like Regular Expressions I've "just learned" half a dozen times already but then forget everything and have to "just learn Git" top-to-bottom again and again. It really is a shame, Git has a great under-the-hood design (excluding poor binary file support), and such a terrible interface/UX that seemingly can never be outright replaced, so we're stuck with a good tool surrounded by needless confusion forever.
- G3rn0ti 4y agoThe way to get „git“ is to think about version management as a concept i.e. starting top down. It’s the implementation details of git that many developers get confused about. But they don’t matter. It’s similar to recursions: You don’t try to understand a recursive function by mentally evaluating it — instead you reflect on its desired return value and how to construct it in the base case.
- seba_dos1 4y agoMy experience is that once you understand the (high level) data structure you're manipulating by using git, you have already made 80% of the way there. I barely know basics of git's interface and have to use tools like `git gui` for anything more complex in my everyday workflow, yet I can manage just fine even when presented with complicated problems, since once I know from the data structure perspective what I want to do, finding a way to do that in git's interface by searching manpages and/or the Web is hardly ever a big issue.
- deleted 4y ago
- ricardobeat 4y agoThis doesn't make git any easier. The synced and update commands are redundant. If you have [pull] rebase = true in your .gitconfig, which you should, both are the equivalent of a simple git pull. Naming a command `squash` when it does interactive rebase is also pretty confusing.
- MichaelCollins 4y agoMissed opportunity to title this "Git Proof Git"
- MetaWhirledPeas 4y agoI understand generally what Git is doing, but when you start throwing in very specific words like "rebase" my eyes start to glaze over. Not because they aren't important concepts, but because I can't stop the nagging feeling that it shouldn't be this complicated (it probably should though). But it isn't complicated! When you use a decent UI tool. I know pretty much exactly how VSCode's UI behaves with Git, along with the Git History plugin. And now I have a perfectly usable workflow and never have to use the command line, and almost never have any merge conflicts. Maybe this is common knowledge to all of you, but it seems to me a lot of people have Git headaches, so maybe they don't know this? 1. Pull latest from remote main branch (select the branch, hit the sync button; permissions structure prevents any accidental pushes) 2. Create new branch based on pulled branch. If I have stashed work, apply it now. 3. Do work 4. Use the + icon to stage individual changes and give them their own local commit 5. Push my local branch to remote (hit that sync button again) 6. In my remote repo UI push the button to create a Pull Request (I assume all shared repos have a PR button somewhere?) 7. Go back to doing local work, but don't commit yet, and continue "not committing" for now 8. After the PR has been merged into main, stash everything including untracked (pick it from the VSCode menu) 9. Go back to step 1, repeat Steps 7 and 8 are how you avoid creating your own merge conflicts. If you keep committing while a PR is in flight, then later on Git will see your earlier changes to a file, and your later changes to the same file, and will see them as a conflict. So just do yourself a favor and never commit to a branch while anything in its history is part of an in-flight PR. Obviously you'll have to deal with merge conflicts with other people but at least you aren't creating your own headache. Git History saves me when I goof up and commit locally when I shouldn't. I just pull up the history and click the soft reset button prior to my commit and presto, I'm back where I want to be (files uncommitted, back in pending changes list). Maybe one day I'll learn the Git command line, but right now why bother?
- blep_ 4y agoStash -> pull -> unstash is just manual rebase, though. You're already doing the thing you're claiming not to do, you're just doing it the hard way. Which is fine, if that works for you! Just know that you're using different terms for the same thing (do some work on top of A, then move it to be on top of B instead).
- user3939382 4y ago.gitconfig: [alias] add-commit = !git add -A && git commit .bash_profile: function save () { git add-commit -m "$*" && git push } Use like: $ save This is a commit message This adds changed files to a commit with this message and pushes it to remote. Also: alias mkpr='git push && gh pr create -d -f -B develop | grep https | xargs printf -- '%s/files' | xargs open' Open a PR from current branch based on develop and open it in GitHub in my browser. Merge upstream changes from develop: alias mduc='CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) && git checkout develop && git pull && git pull --tags && git checkout ${CURRENT_BRANCH} && git merge develop' I have a few more, whereby I skip most of the ceremony with git. Works for me.
- afefers 4y agoThose are really good! Thanks for sharing. Curious to see the others. Are they available somewhere?
- horsawlarway 4y agoCommit accepts the -A flag. You can simplify it to just function save () { git commit -am "$*" && git push }
- user3939382 4y agoYou can. I have it separate for the purpose of composition, sometimes I do 'gac Foo' which stands for 'git add commit' and I push later.
- jovial_cavalier 4y agoIt is an unforgivable crime that Mercurial has been muscled out of the consciousness. It's so much better, on literally every level. Implicit branching + the ability to truly divorce the repo's state from the actual files on the disk (in a simple way, I'm sure you can do the same with git, but it's going to involve a lot of subcommands and flags) are simply too good. Every time I have to use git, I feel like I'm fighting it. I end up coming up with a command that has ten flags and a subcommand that I've never heard of until just now. And when I try to ask people who know better, they agree it's the best way to do it.
- danwee 4y agoGit commit crafting (and rebase to achieve it) is overrated. If you care about crafting beautiful series of commits so that the future readers understands what's going on: don't. Context is more useful to find out why something changed. Example: - you build feature F that is touching N files and M lines of code - you craft your git commits so that each of them is atomic and "understandable" on its own - now if I want to see the context of change for line X, I won't get the changes in all the N files... I'll get your crafted commit that updates only line X (worste case) or its immediate surroundings (best case). But how do I get the full context (i.e., this line is about feature F)? I have to git blame lines around line X and see if I can actually make a picture of the bigger feature. Examples of feature F: a whole new http endpoint touching controllers, services, data access models, middleware. What do you get when people craft their commits? 1 commit for the controller, 1 commit for the service, 1 commit for the data access model, etc. Zero context. Time wasted for the reader
- aulin 4y agoIf you keep merge commits you can get the full diff at once and see all the context you need, if you don't you can still write meaningful commit messages that identify the feature you're working on so that in the future you can still do a diff between the first and the last commit and see it all at once.
- willio58 4y agoYeah if you just use commits as they are intended then the complexity of git drops off massively. I’ve used got for a decade and want to know how many times I’ve rebased? Zero
- throwup 4y agoAfter reading this post, I have another tip - instead of adding `alias.pr` to your gitconfig, you can create a shell script called `git-pr`. Then you can write readable code instead of having to sprinkle extra quotes and backslashes everywhere.
- uwemaurer 4y agoWith https://www.highflux.io/ https://www.highflux.io/ we try to make this git workflow even easier by automating the necessary steps with a simple UI. You can just work in your feature branch, your changes get automatically rebased and when your done your branch gets merged as a single commit. We are still in early development, always looking for feedback :D
- palata 4y agoI think people mostly don't care, but I personally sign my commits. And if you rebase, you lose the signature (well, maybe the person rebasing re-signs it). But then it means that my commits are not signed by me anymore. Feels like an interesting point against rebase workflows to me, but nobody mentioned it, so maybe it's just me.
- dmuth 4y agoI wrote an open source project that may be useful to people here: https://github.com/dmuth/git-rebase-i-playground https://github.com/dmuth/git-rebase-i-playground It lets you create a Git repo with synthetic commits and has sample exercises for doing different things within that repo, such as removing commits or squashing commits. (along with hints and answers) Building this project helped me understand the ins and outs of Git much better and I suspect there will be value for anyone else who works through the examples.
- sixstringtheory 4y agoThis seems like something that should be used in hiring filters, maybe right after fizzbuzz.
- jgworks 4y agoThis is off topic: I have a dumb git question and I can never seem to formulate a google search that will help me. I use a Mac and for some reason I am able to use `head` (lowercase) instead of `HEAD` (uppercase) in every command and its trained in my muscle memory. So when I go to another computer, this shortcut isn't there, so when I type `git reset --hard head^` I get an error, and I have to go back and change it to `git reset --hard HEAD^`. Anyone know of a configuration option or something somewhere that I can enable this?
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- trillic 4y agoMacOS defaults to a case insensitive filesystem. Branches are just a commit tag which is just a git object which is a file??? I think? Everything is a file?
- Anktionaer 4y agoNot to worry, I am a professional googler https://stackoverflow.com/questions/25976794/is-head-in-git-case-insensitive-on-all-platforms https://stackoverflow.com/questions/25976794/is-head-in-git-... ...I keep finding out neat new stuff about git plumbing.
- periodontal 4y agoThis is probably due to the underlying filesystem being case insensitive on Mac. As a hack, you can create a symlink alias on a per repo basis. ln -s HEAD .git/head
- quesera 4y ago> Anyone know of a configuration option or something somewhere that I can enable this? I'd suggest that you retrain yourself instead. "HEAD" and "head" are not the same thing, and any fakeout configuration to change that will also be nonstandard and not available everywhere. The underlying issue is that HEAD is the label Git uses for the reference to the top of the repo. It's saved in the filesystem as .git/HEAD. MacOS filesystems are case-preserving by default. Linux/POSIX filesystems are case-sensitive by default. I consider this a bad default setting in macOS. Try "cp FILENAME filename" sometime. :( Anyway, consequently, on default macOS, "head" will be remapped to "HEAD", if "head" does not exist. Watch out for "Head" and "hEaD" though. Of course those won't happen in normal Git usage (though they could be valid, and different, tag names!). My suggestion is to not let bad macOS defaults creep into your habits. And to not make things even more weird by trying to reproduce their bad behaviour in non-macOS environments.
- prepend 4y agoI just never rebase. Am I missing out? It seems the only major advantage is to reduce the number of items in the history and that doesn’t seem very important to me.
- __blockcipher__ 4y agoYes, you're missing out. Rebasing isn't about reducing the number of items in history, although it can do that too. It's about having a sane, readable history. If you write two commits in your local feature branch, then pull master in and generate an ugly merge commit, and then stack two more commits on top to your local feature branch, and then finally get all that mess merged to master, you have a difficult to read history because of the merge commit randomly in the middle. Whereas if you instead rebase onto origin/master (after fetching of course), you get a nice history where your feature branch commits are cleanly on top of origin/master, so there's no crazy merge commits in the middle. Most people just use git as a fancy save button, and therefore never actually use the git log / git blame to answer questions about why some part of the codebase is the way it is, and therefore they never realize why their merge commit insanity is so destructive to the usability of the git log.
- jcon321 4y agoFor a 1 man team there is no point. Even for a 1 man team with a local and remote repo there is no point, because your local branch is always the same as the remote branch. For a 2+ man team that does not protect the remote repo (i.e., don't require merge/pull requests, and you can commit/push directly into remote branches), then there is no point because... When you go to push a branch and remote complains about changes existing on remote, so you must pull first. You issue a pull and that does a fetch/merge into your local (commits are overlaid in order by date committed - some people complain about this and is why they rebase (commits from remote are back filled, and then your commits are inserted)). For a 2+ man team that does protect the remote repo, and does require merge/pull requests then an explicit rebase or merge is needed, sometimes. At the end of the day you should be creating a merge/pull request from a source branch that has all of the changes as the remote target (at that point in time) to help the reviewer/approval only see your changes. If you updated your local branch via a rebase then the commits related to your changes are all in order, if you updated your local branch via a merge then the commits related to your changes are interlaid between other commits that happened around the same date). But really that's only a problem if someone cares to use git-log and not the 100 other ways to review history.
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- nerdponx 4y agoUgh, that `pr` alias gives me shivers. Just write a standalone script that you distribute to teammates! You don't get extra points for jamming it all into a single string in a config file.
- jcon321 4y agoIdiot proof git is handled by protecting ALL branches and requiring a merge/pull request. Not a fan of aliases unless created and used personally. I'm a tech lead for 2 large scale web projects. Rarely will I traverse git log for anything besides the last few commits. If I ever wanted to see the history of something I would just lookup the merge/pull request, or look at the blame on individual files or lines within that file. Having a non-rebased commit history at that point is much more clearer on why/what changed. I guess anyone who would care for a pretty git-log does not have adequate tracking outside of the source code for requirements --> implementation. Guess I'm used to more stricter guidelines, because I could never see myself working on a project where something is committed that didn't derive from some type of identified requirement.
- pierrebai 4y agoI fail to see what anything you state has to do with rebasing. Rebasing ensures all commits from a feature branch are contiguous. Rebasing + squash ensures the main branch is not polluted with a myriad of useless intermediate commits no one is interested in. It also allows combining multiple commit message into a more coherent explanation of what changed instead of multiple tid-bits.
- jcon321 4y agoI fail to see your misunderstanding of what I stated. Rebasing is all about a pretty git-log, a pretty git-log is all about looking up why/what something changed. Everything I stated is about why you don't need a pretty git-log to know why/what something changed... Hope you don't talk to people at your day job like that. Squashing commits of a feature branch via rebase is not the same thing as rebasing a local feature branch with the intended remote target. Anyways, squashing is almost worse. Imagine doing a git blame on a line only to see a large commit of x amount of other changes with a summary about the global feature instead of an individualized commit referencing the line changed more closely. I am interested in those myriad of useless intermediate commits as you put it.
- hqudsi 4y agoyea I do interactive rebase all the time on my local git to clean up my commits before I push them up. I also started doing `git commit --fixup` when doing cr fixes so I can just autosquash the fixes - `git rebase --autosquash` So yea I think rebase and merge commits both have their place within a workflow.
- Sverigevader 4y agoNice page! Very well made and great explanations. However; I'm a big fan of aliases in git, but I don't think this is the way to go personally. Knowing the difference between rebase and merge is vital, and I think it's worth the time investment to learn git properly. It took me 1 month of painstakingly learning the git CLI and I'm happy I spent the time. Before that I was using a GUI and was essentially afraid of git. I'm no longer afraid. Instead I'm actively exploring ways to do things faster and/or smarter every day. This happened when I switched jobs recently and came into contact with a fantastic developer and patient teacher. Doing it myself would have taken a bit longer and I wouldn't be able to see how much it would be worth it. I'm enjoying a rebase workflow everyday. And I especially like the -i flag for interactive rebasing; git rebase -i Same with -p for interactively adding code/files before commits git add -p I read the first three chapters of the git-scm book[0] and it made a world of difference in understanding what's actually going on. [0] https://git-scm.com/book/en/v2 https://git-scm.com/book/en/v2
- amelius 4y agoThe paradoxical thing about Git is that it saves all history so you can undo anything, yet at the meta level this is quite hard and you can still get in a lot of problems if you are not careful.
- coding123 4y agoI love git, but I have to be honest about one thing: It's definitely hard on purpose and introduces hard on purpose features (and naming conventions) to weed out people. rebasing and squashing and tracked/untracked. Yes they all have a place, but has anyone noticed with SVN it's just commit, merge and branches. Would it be impossible to make git with svn's UI?
- Arelius 4y agoYes, svn hides and pushes most of the complexity to the users workspace, and just gives up when any sort of complexity happens. Git could clearly be improved, but much of sun’s ease is due to hiding the complexity of development.
- corytheboyd 4y agoAliases don't make git easier to understand, they make one specific git command require typing fewer characters to run. I am not against making aliases, but just saying, if you don't have an understanding of the commands they run, you'll still one day be in a state you don't know how to fix, and THAT is when people "lose their code" etc. You use git every day, it's worth learning and understanding. You don't need to be a pro, but you need to be good enough.
- throwaw20221107 4y agoThe only reason people lose code is because 1. they didn't read this one diagram: https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-... 2. And then they run `reset --hard`
- veilrap 4y agoI'm mostly with you, except, `git reset --hard` is relatively easy to recover from. `git reflog` generally can fix most `git reset --hard` commands. On the other hand. `git checkout .` with unstaged changes tends to be the most common way I've seen people lose code via git.
- throwaw20221107 4y agoThat's fair. Both overwrite (edit: seemingly overwrite) (un)staged changes. But `checkout` requires less hyphens. I feel like all of this would be resolved if my boy Linus had renamed `git add` to `git stage` or `git prepare` or something more clear. Or added some warning, like "all this stuff you haven't committed yet; it's not managed by `git` so don't try to overwrite it all using `git` until you've committed some of it."
- throwaw20221107 4y agoThis is another argument why "not squashing is bad"; because it discourages people from committing.
- stevage 4y agoFor me this is another painful reminder of what git could have been. Imagine if it had been this ergonomic from the start. Everyone would have the same set of commands. Whereas if you adopt these aliases you can't easily discuss any git related issue with someone who doesn't use them.