5 ms·
I have a dedicated shell script for each thing I do in git, because it is impossible for me to memorize the original syntax and I'm terrified I'll gut the repo
by kerblang 6y ago
I have a dedicated shell script for each thing I do in git, because it is impossible for me to memorize the original syntax and I'm terrified I'll gut the repo by getting a flag wrong. I have an "undo" script, that just gets rid of unstaged changes, a branch deletion script for removing local & remote branches, and so on. I just take my scripts with me everywhere I go. They're not ingenious, just a necessity. I advise doing this.
People like to tell me, "Oh see you just need to understand that git has something called a 'directed acyclic graph' blahblahblahblah" and no, that has nothing to do with it. It's just incredibly arcane and bizarre syntax for the most obvious everyday operations. But since my scripts make life easy, I sort of don't care at this point.
Also I don't rebase and thus I don't force push and thus I don't reduce my repo to a pile of burning rubble and work til 3AM repairing it and if people ask me to rebase enough times I'll threaten to literally take a dump on their desk/car/front porch which usually makes them stop. I advise doing this as well.
- domano 6y agoI have never understood the benefit of hiding away the actual history. Many people i know find rebasing to be superior because you have this pretty history, but i actually love having the ability to understand what happended when exactly as it happened in reality.
- formerly_proven 6y ago"No broken commits" is one, "nobody cares how often you merged master into your feature branch" is another. Most of the real reasons revolve around making a bisect quicker and easier.
- kerblang 6y agoIf it helps any, I usually squash-merge my final output into sparkling, concise commits with nice messages (my original branch usually has "x" for every commit message). And yes I have a dedicated script for squash-merging too...
- patrickthebold 6y agoMy preference is to disallow/disable fast-forward (and squash) merges to master, and then use --first-parent when you want the clean non-broken easily bisectable history, which is most of the time, but the full messy history is still there. I actually don't care so much about seeing the messy history, but its annoying when everyone on a team is always rebasing there branches and force pushing them. I've definitely been at places where one team member is waiting on another to merge their code to master so they can start working. Of course, rebase all you want locally before you push.
- Buttons840 6y agoTry not pulling other team members branches. What I mean by that is instead of having your own branch HEAD/tag (whatever the term?) for their branch, do `git checkout origin/their-branch` when checking out their branch. Git will complain about a detached HEAD, that's OK. Then later when they rebase and force push, just do the same thing again, and you never have to worry about making sure your own local branch for their branch is in sync.
- vendiddy 6y agoI agree here. It feels like the popularity of git has lead us to believe that you either have to choose a clean history or the real history. But I imagine there exists a design for a source control system where you can preserve history and also provide a clean interpretation of that history. For example, why does rebase have to be a destructive operation?
- sangnoir 6y agoThis depends on mindset: what do you consider the primary building block for a changeset - the changes, as made by the developer in chronological order or changes that are related by logic, despite the time (and order) in which they were made. I favor the latter approach - developers in the future will have no use in knowing the different approaches I attempted before coming to the actual solution - that is noise. What they should care about (IMO) are logical commits with related changes. Additionally, "preserving detailed history" makes cherry-picking fixes across multiple release branches a royal pain: not everyone has the luxury of having on single, ever-green release branch. So having a feature/fix in a single, self-contained commit that hides away the actual history is a good thing in this scenario (with the added bonus of not running into fluff/half-cooked commits when running git bisect)
- domano 6y agoI usually squash my commits before merging, i think that makes things easier while still keeping the chronological view intact
- ivanche 6y agoIt's not about history. It's about correctness. Let's say there's a master branch at commit M1. You branch off of it. You develop your feature branch. In the meantime, master is at commit M26. Now on your feature branch all your tests pass, maybe even there's no merge conflict with the current master. But! Master's behaviour changed and you have no idea about it, and no idea whether it affects your branch. You merge feature to branch and kaboom! Frequent rebasing protects you from this.
- domano 6y agoYou could also frequently merge master into your branch and squash at the end.
- ivanche 6y agoBut squashing changes chronological view, right? Either you want "real" history or not. If you're already willing to do that then with the same amount of work you get cleaner history with rebasing, i.e. no intertwined branches.
- formerly_proven 6y ago> I'm terrified I'll gut the repo by getting a flag wrong. There are pretty few operations in git which can't be undone by a quick glance at git-reflog.
- kccqzy 6y agoOr even just frequent backups. A coworker of mine used to copy the entire on-disk repository including the .git directory before doing anything slightly unusual in git. Very paranoid I thought, but then he could recover from a fat-fingered wrong flag very quickly.
- jollybean 6y ago"Or even just frequent backups." ? Well, git is supposed to be that 'history' for us. I understand it's not exactly a backup, but it is pragmatically that. I don't want to have a 'backup of backup' I want to feel confident with what's there.
- dockd 6y agoWhich is ironic since source control is supposed to prevent the need for manually making backup copies.
- rualca 6y ago> Or even just frequent backups. A coworker of mine used to copy the entire on-disk repository including the .git directory before doing anything slightly unusual in git. To recover from commit screwups, it should be enough to just export the git repository somewhere else like a remote repo, or even just apply changes in a separate branch. It just seems that a developer is doing something extremely wrong with their repository if they can't recover from their experiments by checking out a branch or commit.
- da39a3ee 6y agoOr slightly more comfortable —- create a temp branch before doing something. Of course that’s basically the same thing under the hood.
- selfhoster11 6y ago> I have a dedicated shell script for each thing I do in git, because it is impossible for me to memorize the original syntax and I'm terrified I'll gut the repo by getting a flag wrong. I have an "undo" script, that just gets rid of unstaged changes, a branch deletion script for removing local & remote branches, and so on. I just take my scripts with me everywhere I go. They're not ingenious, just a necessity. I advise doing this. I don't blame you, and I'm actually an enthusiastic proponent of this approach. It's just more ergonomic. I personally have an extensive list of idiosyncratic aliases that perform (conceptually) high-level operations on top of my git repo to let me work faster and use up less mental power to reason about what I'm doing. I use them at home and have carried them from one job to another (and am planning to do so indefinitely), taking care to keep things bash-based and portable between OSes. I barely ever drop down to using built-in Git operations directly, besides `git push`. I don't need to, and I don't want to, even though I know enough about git to untangle complicated rebase clusterf*cks by reasoning about and operating directly on the DAG if I have to.