20 ms·
Git is my buddy: Effective Git as a solo developer
- sillycube 6y agoAs a solo founder, I only use git add, commit, push, pull, clone. That's all I need
- Sodman 6y agoAs somebody who will occasionally have a spurt of 2 weeks hard work on a side project in the evenings, before putting it back down for 3 months, I think branches and tests are well worth it. As the saying goes, there's nothing worse than reading code you wrote a year ago. Having every commit in a branch pass all tests is a little overkill, but gating merges to master/main on tests passing and then having branches squash before merging seems like a happy middle ground. At least that way every commit in master/main has passed tests.
- remram 6y ago> What if I told you Git can be a valuable tool without ever setting up a remote repository? Even if you don't set up a public repository, having a remote one can be a good idea. The .git folder is surprisingly easy to trash. Any box with SSH access works, and GitHub/GitLab offer private projects that you don't have to configure further than a name. My latest mistake was running 'rclone sync', which it turns out deletes files missing from the source without confirmation contrary to rsync.
- rrosen326 6y agoI'm also a solo developer and use git in a much less sophisticated fashion. I tend to use it as, "freeze my code here, so in case I f something up, I can get back to a moderately clean state." It's kind like a snapshot-based local history. And, quite frankly, I rarely revert one, but it makes me feel safer. I don't care if I have a lot of commit messages that say, "interim". The good ones are clear. Is this a terrible coding practice? I don't have enough non-me experience to know what an anti-pattern this probably is. I probably won't change my process, but I'm curious.
- ChuckNorris89 6y agoI thought I was the only one using guy like this.
- scaladev 6y agoJust squash the junk commits with rebase when you are done. It keeps the history clean and you have many points to revert to.
- edu 6y agoIf it works for you it's fine. I used Git in different ways depending on the projects, on some solo projects I do like you say (similar to saving a game to be able to go back). For some other solo projects (with a longer lifespan or more critical) I follow Gitflow and I am more strict with the process.
- Ajedi32 6y agoPretty much what I do too, even working in collaborative projects. Once nice thing about git is that it makes it easy to go back and clean up your history with rebase before publishing it to others, so you can make as big of a mess as you want in your local branches without anyone else having to see it. So yes, having "interm" or "wip" commits would be an anti-pattern in a shared repo, as it makes it harder for others to see what changes you made. For a local branch though; not a big deal.
- rrosen326 6y agoSo maybe that's the idea for my projects that I make available to others. Be a bit more deliberate with branches, allow them to be junky, and clean up when I merge to master. That seems like the best of both worlds with minimal effort. I think I'll even try it.
- kop316 6y agoThat has been how I have started to do it. I make a new branch, make a mess of it (until I am finished), then merge it back into the original "golden" branch.
- pizza234 6y agoI have a quite strict solo-SCM workflow as well (including PRs!). The reason is that the SCM is not just a tool - the history of the codebase follows the thought process of the developer. More structured history == more structured thinking. Cleaner history == cleaner thinking. Documentation (traceability etc.) is certainly a benefit, but in this sense, it's part of the smaller picture.
- mettamage 6y agoThis comment reminds me of writing structured articles: writing structures your thinking. I guess having things in a clear workflow does the same thing.
- antipaul 6y agoGitHub too is useful for solo work: you can code review your own code. I’ve found it useful because it’s in a separate context/UI (GitHub web view) as opposed to your code editor or even git diff on command line.
- WorldMaker 6y agoI tell people all the time not to underestimate the value of PRing your own code even if you are the only one reviewing the code. You can still use GitHub's merge time checks (including setting up your CI/CD builds and PR integration), even if it is just a solo project. You can use PR merge commits as your "clean level" instead of worrying as much about rebase/squash (and tools like --first-parent in git log and git bisect from your main branch).
- SilverRed 6y agoI always do a file by file sweep of my merge requests on gitlab before sending them to peer review. Usually it only finds commented code or console logs but its worth it and pretty fast to do a final check.
- Droobfest 6y agoYea... no. An overly clean git history for me is a sign of too much perfectionism and greatly reduced productivity. When I code I usually have a general idea of the stuff I want to include in my branch, but then I stumble upon bugs or code couplings which I need to fix for my feature to work. And then I include the fix into my feature branch, because it's just tedious to switch all the time and create 5 interdependent branches that need to be merged together anyway. Also as long as the feature branch itself is fairly clean then I don't give a rats ass about atomic commits. And commits having to pass tests is just ludicrous. That's what the tests are for, so you can fix it before merging the branch. Don't go crazy on the commit level.. It depends a bit on the project, and how public it is. But in the end your git history never provides any benefit to customers and doesn't make your code better by itself. I hardly ever rewrite or rebase commits unless there's a good reason for it.
- lwall 6y agoKind of disagree. As a developer who works with code base that's got a git history going back over a decade and lot of legacy parts that haven't been touched in a long while, written by devs who've long since left, I fairly frequently wish they'd been more careful with the commit history. You do mention project context as being relevant, but if bug fixes and refactoring _can_ be decoupled, it's a kindness to pull-request reviewers (if there are any) to do so and keep PRs small. It's also helpful if something needs to be rolled back if the commit history is fairly coherent.
- Droobfest 6y agoWell I'll admit there is still a balance to it. I'll just say that the emphasis should be on clean branches and PR's much more than clean individual commits. And on good code much more than clean git branches. If there's too much ceremony around branches and pull requests I tend to avoid small fixes because it's just much work and that definitely doesn't improve the quality of the code.
- slingnow 6y agoWhy are you comparing advice meant for _solo projects_ to a 10 year old legacy codebase written by many different developers?
- moosebear847 6y agoAnyone know a clean way to have nested git projects? Every time I make a commit in B (the nested git project), there are changes in A. Previous searching of a solution was hard to understand..
- sebmellen 6y agoPerhaps you're looking for something like submodules? Just create a Git submodule, and then push from within the submodule, like so: https://stackoverflow.com/a/5814351 https://stackoverflow.com/a/5814351.
- ctb9 6y agoTen years ago I was told to never use Git submodules. Five years ago I inherited a project that had four repos sharing a Git submodule. Now I tell people to never use Git submodules.
- sebmellen 6y agoI think it very much depends how you use them. A great option to manage submodules is TwoSigma's "git-meta" https://github.com/twosigma/git-meta https://github.com/twosigma/git-meta. There's also just "meta" which is a cleaner way to approach the functionality of submodules https://github.com/mateodelnorte/meta https://github.com/mateodelnorte/meta.
- MaxBarraclough 6y agoI've not used them myself but a lot of people strongly dislike git submodules. A recent thread on the topic: https://news.ycombinator.com/item?id=26165445 https://news.ycombinator.com/item?id=26165445
- WorldMaker 6y agoPerhaps you would like one of the monorepo management tools like Lerna? In general, the best advice is to avoid nested git projects as much as possible (even though tools like git submodules exist, they are more footguns than you want them to be). You either want to reorganize your folder tree so that your git projects are only ever side-by-side rather than nested, or that there is only one repo for all of them ("monorepo"), depending on your preferences and when/how you expect to share them.
- dmitryminkovsky 6y agoWhen I was a new developer and first learned Git, I felt compelled to use Git the "right" way. That is... small commits with clean messages, things described in this and other posts. But, as I spent more time programming, I developed different Git habits for different situations: - Solo explorative work: working on a feature, many small commit messages create nothing but noise. Trying to come up with wording for these commit messages is mostly a drain on my mental energy: there is an infinitesimal chance I'll need these commits later. In such cases, I prefer to maintain large "checkpoint" work-in-progress commits that are the result of near-continuous `git commit --amend`s so that I can use `git status` to see what's changed since my last checkpoint, and easily revert to the last checkpoint. If this fails me, I can almost just as easily refer to the reflog to find some changes. The reflog, in my opinion, is an extremely under-utilized tool. `git diff HEAD@{2}..HEAD@{0}` allows me to see what's happened in the the last two times that I updated my checkpoint. Since this is active work I'm doing right now, I have a good sense of what happened and when, all without tiresomely writing commit messages that will be a bunch of gibberish in two days. When I'm satisfied with with the work on a checkpoint commit, I reset the branch to the previous real commit, and then incrementally create real, meaningful commits from the accumulated work, that have some chance to be useful to me in the future. - Working on patches and bug fixes for live systems or production libraries: small, atomic commits that include tests for the patch are the only way to go. I believe the "correct Git" approach that is widely espouses is targeted to this use case, but not explorative feature work. Or maybe that's just me. Wondering if anyone else codes like this.
- froseph 6y agoI do lots of small commits as save checkpoints and new branches for each point of exploration. Rebase/reset to create clean commits. Each final commit is a complete thought.
- dmitryminkovsky 6y agoYeah sometimes the small commits with message is useful for me too instead of amending a big accumulated check. Doing this now, in fact. It's all so situation dependent.
- zippergz 6y agoI'm happy for this person if this works well for them. For me, no thanks. One of the reasons I feel much more productive as on my solo project than at work is that I don't have this kind of overhead. I don't need to write tests for everything (I write them just where they add value). I don't need to follow some strict branching standard. I can commit in chunks that make sense to me, and adjust as needed for the situation. From my perspective, a lot of this kind of rigid process is important and valuable when you are working with a team, but is counterproductive when it's just me. I know the tradeoffs of the corners I cut. I have the experience to know, for example, that's it's not a safe assumption that I will understand my own code a year (or even a month) from now. But the solution to that is to throw in some freeform comments that jog my memory; not to implement a heavyweight documentation system. Everyone should work in the way that makes them the most productive and happy, but I don't think it's a good idea for solo developers to bring in practices that are designed for team collaboration without really understanding what value they will get from the extra effort.
- twodave 6y agoDefinitely--when working solo I tend to only write tests for things I actually want to run in isolation (and usually just to save time running the full codebase) or to establish some concrete expectations that I need to be aware of changes to (e.g. specific user scenarios that are critical to the thing working). These tend to overlap a lot.
- at_a_remove 6y agoI agree wholeheartedly. I was a solo developer. We "transitioned" rather abruptly to the kind of workflow you would expect from an organization with hundreds of developers once we hired a couple more programmers, despite it being a poor idea, because we were still spread out among so many different projects. In retrospect, all of this turned out to be resume-polishing and practice runs for one of the developers and my manager; they blasted off to large organizations rather promptly. All of it left a bad taste in my mouth and some rather negative feelings associated with git, which certainly are not helped by git's porcelain. There's an element of cargo culting against the practices of big SV organizations, but there's a very long tail of solo developers out there, and figuring out where you sit and what tradeoffs are required can be tough against the constant din of The Way Things Are Done.
- yboris 6y agoRelevant useful tool: diff2html - a CLI that lets you quickly see an HTML output of all uncommitted changes you've made (or compare against a branch). https://diff2html.xyz/ https://diff2html.xyz/ I have an alias `alias diff='diff2html -s side --ig package-lock.json'` which shows a side-by-side comparison of my changes. Highly recommend!
- remram 6y agoFYI Git has a difftool setting/feature specifically for doing diffs through an external command.
- dukeofdoom 6y agoJust curious, I'm also solo developer. I push my local development to git (bitbucket), then do a git pull in production server to sync the two. Is this how most people do it? The only downside I found, I need to reboot the server for the django app to update to the changes. So I take my site offline for 3 minutes or so.
- twodave 6y agoMost decent CI tools will just clone the one branch needed for deploying and build/deploy from there. Cloning it fresh each time can rule out artifacts from past builds having an impact on the current deploy.
- jedimastert 6y agoIt's not necessarily bad, but there's plenty of steps to automate away, with two ideas: * You can use your production server as a "git server" without basically any overhead * You can set up scripts that run on git events. Basically, you can push directly to your production server and then deploy using that those event listeners Here's a better explainer https://tqdev.com/2018-deploying-with-git-push-to-production https://tqdev.com/2018-deploying-with-git-push-to-production As for having to reboot your server every time, I have no idea, although that seems like a long time. I'd expect less than a minute, but I don't know much about django
- cashewchoo 6y agoI use docker extensively, personally. Modern web app frameworks, especially those in python and ruby, are super annoying (imo/ime) to operate on a bare metal host, because how pip/gem install dependencies by default is just a mess that's impossible to isolate. Pre-docker, I had no end of headache where touching any deployed thing broke all the other sites due to dependency garbage. Rbenv/pipenv/etcetc are language-specific, non-trivial band-aids and I don't like wasting brain cycles on them. Docker makes it so easy to deploy and operate programs that I even use it for ecosystems that don't "need" it, like Java. Also makes backups super easy because it's just backing up the docker volumes.
- 6y ago
- twodave 6y agoThe "every commit must be independent" ideology sounds nice when you write it down, but often you'll have such large changes that in order to make them independent you'd have to basically finish an entire feature. In those cases I tend to just indicate WIP (work in progress) in my commit messages with a brief snippet about what progress was made. This way, if you skip all the WIP commits you'll have mostly runnable code, and if you want to review a PR commit-by-commit it's easier to see what was being attempted in each commit than to only look at the feature as a whole.
- tonymet 6y agoGit is designed to make it easy to restructure commits (rebasing, resetting, selective adding ) . Don’t be so obsessive with it . Track your work and at the end of the day , restructure your work so that you can manage it well (for posterity or collaboration )
- bogwog 6y agoWhen I'm working solo, the only reason I use git is to sync my code between my desktop and laptop, and to "back it up" to my remote server for peace of mind. I have never in all of my years working solo on projects needed to revert my history to debug a problem (excluding CTRL+Z of course!). If I am experimenting with something that I don't think will work, then I use a branch. The amount of work to maintain a clean history and disciplined git practices is not worth it. For non-solo projects with even just 1 extra developer, then totally. Otherwise, you're just wasting your time...IMO. But honestly, the nice thing about solo work is that you can do whatever you want, and confidently ignore people who think they know how you should work better than you do. If this helps you be more productive or organized, then go for it. And worst case scenario, you're less productive with your project, but you become a git wizard.
- cashewchoo 6y ago+1 to the sentiment. I will say I've occasionally used git-revert, but it's usually when I'm half-expecting to revert it but want to see how it behaves in prod.
- warmwaffles 6y agoI try to keep my commits as compact as possible instead of just saying "yolo here is 9000 lines of code". But, there are times when I am just crushing through the initial bits of a project where it just keeps getting in the way.
- acemarke 6y agoHeh. On my teams, I _am_ "that one guy who knows more about Git" :) I recently wrote an extended post that aims to help devs understand how Git works, available Git commands, and techniques for using Git effectively: https://blog.isquaredsoftware.com/2021/01/coding-career-git-usage/ https://blog.isquaredsoftware.com/2021/01/coding-career-git-...
- phailhaus 6y agoAs others have mentioned, trying to keep your commits atomic while simultaneously working on several features at once is basically impossible since they're immutable. And given that modern source-control platforms (e.g., GitHub) support squashing on merge, it's pretty much unnecessary. You get "atomic commits", "every commit has tests", even "clean git history" just by squashing your PR's on merge, so PR's become atomic units of work. Which makes sense! Every PR is an incremental addition to a project that is reviewed as a unit and committed all at once.
- nine_k 6y agoSmall incremental commits on a feature branch, which allow for fine-grained development and review. Large squashed commits on the main branch, each representing an approved and merged PR, which allow for a reasonable history of features and fixes.
- Ericson2314 6y agoMy very first programming project, porting https://github.com/ericson2314/voxlap https://github.com/ericson2314/voxlap, was rebase-heavy git to always be able to bisect my many mistakes. Other people tried to contribute but it didn't go too well!
- freedomben 6y agoI do a lot of solo development and I always use git. I'm definitely a lot less disciplined about small atomic commits than I am when collaborating, but Git is still very valuable to me. I use it for a few things: 1. As a collection of notes describing what was in my mind when I wrote that code 2. To allow me to work on different machines. For example I have an app where some of the work I do is directly on my staging server (long story). It's nice to be able to commit and pull there and to my local workstation 3. So I can rollback to known good states. Doesn't happen often but has saved me a few times over the years!
- yummybear 6y agoYou really need to be in a git-first mindset to follow these. Not saying that's a bad thing, but for me at least as a solo dev it often comes as an afterthought and breaks pretty much all the rules. When developing only with yourself, git quickly ends up becoming a cloud backup. It shouldn't but...
- mustak_im 6y agoThis is a nice blog post and it may make you an effective Git user as a solo developer and that's about it. I'm sorry when I have to squeeze as much as possible into the limited time I get for my side projects after a long day of work as a professional developer - I have one rule: get stuff (that matters) done.
- yters 6y agoOne of the neatest aspects of git that I never see used is delta debugging, where git automatically finds the code that introduced a bug through binary searching the commit history. This requires many small commits, which is tedious.
- olav 6y agoSome developers favor tools other than Git. For example, D. Richard Hipp, the developer of SQlite, uses the Fossil Distributed SCM to some success https://fossil-scm.org/ https://fossil-scm.org/
- strzibny 6y agoThis is a good idea how to do git in a team. For solo use, you can actually give yourself a little bit more slack.
- tpmx 6y agoGit is way too complicated for a solo developer. It's great for Linus' Linux code management - that doesn't mean it's great for every single developer situation. As a solo developer/potentially newbie, I think it's better to spend brain cycles on actually learning programming, than to learn the idiosyncrasies of some crazily complex tool like git.
- offtop5 6y agogit init git add . git commit . -m uh git push Doesn't look too hard to me. Particularly when I'm going to rewrite my system, I'll go ahead and check out a new Branch so I don't freak out when I break everything. Infact I tell a developer to learn git first. The only time git becomes an issue is when you have large binary objects, like with a video game. Git LFS is pain.
- tpmx 6y agoI figure it takes 3-4 weeks for a typical newbie developer to learn git in depth. That's too much compared to the benefits. Git is way too complex and the CLI is badly designed, especially for a solo developer. The crux with git is that you really do have to learn it in depth, if you want to be self-sufficent in the end.
- golemiprague 6y agoLearning to commit and push doesn't take that long, that's enough to maintain history and backup, which is what most sole developers need from git in the beginning. Then you learn branch or diff for cases when you need it. Then when you need to revert back to some older version you learn that. Then when you need to automate deployments you learn a bit about tagging or some branch structure for development, bug fixing, deployment whatever. You don't have to learn it all from the beginning, you learn as you go, that's at least how it works for me. Then you might learn bits and pieces for one time use and forget it later because you don't need to use it again for a year. It is just the normal pace of learning git, you don't have to grok it all at once
- offtop5 6y ago
- PeterWhittaker 6y agoWhether a branch should do one thing or a collection of things, for me, depends on how big/complex is the thing. If I’m making a very small change, e.g., a fix, I’ll work on master directly (personal work only! Shared work always uses the way we’ve agreed to work!). A slightly more complex change or an exploration or experimental change will get its own branch. A very complex change will have a base branch and feature branches off that base, possibly with issues, one per feature, merged into the base branch, which will eventually be rebased on then merged into master.
- 7800 6y agoI love this title.
- legends2k 6y agoNice article. I have a similar one where I have 2 line explanations of more nuanced Git commands for some situations. Git Wizardry: Obscure but useful Git incantations https://legends2k.github.io/note/git_nuances/ https://legends2k.github.io/note/git_nuances/
- luord 6y agoDamn, I must say that it's rare that I do find something so compelling yet so radically different to how I usually work[1]. Which is not to say that I think I'm an expert; if anything, it's because I don't know how much I don't know. I must try this. [1]: Pretty much the usual gitflow with sequential commits of partial work on a branch—often with commits fixing previous errors in the branch—until I deem it finished.
- auraham 6y agoAs a beginner, I am comfortable with git push, pull, commit. However, it is hard to realize whether a practice is good or not. For instance, I do not know if a rebase or squash is an accepted practice (or under which scenario is a good idea).
- greyhair 6y agoI have been using version control of one flavor or another since I started down this career path in the mid 1980s. My home projects went from SCCS to CVS to SVN to GIT over the years. But there was always some form of version control, even for my home projects. I generally followed what I was using in day to day work, but with out all the process modeling, just the base version control. Briefly in the mid 1990s I also dabbled in 3DFS and Plan9 for date based file systems. Those sort of negated the need for explicit version tracking systems, but neither idea endured the test of time.
- greyhair 6y agoalso, git stash is your friend. and after you stash, it isn't always 'git pop', but possibly 'git apply' There are times when I have three (or more) stashes stacked up on any given branch. I know I have reached a cohesive set of changes when I am ready to 'git stash drop' every one.
- Cyberthal 6y agoThis seems like a classic case wherein messy execution should be followed immediately by meticulous cleanup. Messy execution exploits top-of-mind opportunities without permitting administrative overhead chores to distract. Immediate meticulous cleanup constructs an idealized legible history, with the advantage of familiar recency. The human brain itself works this way, consolidating long-term memory overnight during sleep. The next question is how best to implement this workflow in git. One option would be to use complex arcane git commands to transform a messy actual work history into an idealized legible official record. Even if the user performs this transformation perfectly, at minimum it causes a loss of information about the actual work history, by altering messy commits. Therefore it's better to write completely new commits for the official record. One's idiosyncratic work history doesn't belong in the public collaboration git repo. I find it easier to use separate git repos, one personal and the other collaborative. I transfer info between them only via manually syncing the working trees. It may take syncing from multiple personal commits to update the official record sensibly, which sounds like a burden, until compared to the alternative of trying to understand a mysterious ancient official commit embracing multiple unrelated changes. Code spelunkers unsatisfied with the terseness of the official record should be free to investigate the contributing dev's personal repo to sort through his chaos for clues.