[HN Gopher] Git is my buddy: Effective Git as a solo developer
___________________________________________________________________
Git is my buddy: Effective Git as a solo developer
Author : vortex_ape
Score : 298 points
Date : 2021-02-23 16:19 UTC (6 hours ago)
(HTM) web link (mikkel.ca)
(TXT) w3m dump (mikkel.ca)
| remram wrote:
| > 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.
| antipaul wrote:
| GitHub 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 wrote:
| I 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 wrote:
| I 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.
| phailhaus wrote:
| As 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 wrote:
| Small 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.
| paledot wrote:
| Nothing says "readable history" like 1000 lines in a single
| commit.
| Sodman wrote:
| As 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.
| zippergz wrote:
| I'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.
| allenu wrote:
| I was going to post that on my personal projects I'm
| intentionally fast and loose with git and then saw your post
| which sums up my thoughts.
|
| With personal projects, the most important thing to maintain is
| interest and momentum. Best practices aren't so useful if you
| end up hating working on your project because of self-inflicted
| process.
|
| Certainly, if you are using your project to improve best
| practices or learn "correct" ways of doing things for some
| other long-term career benefit, go for it. What I've learned,
| however, is that personal projects where I've spent more time
| doing "meta-work" were the ones where I never shipped anything
| or just spun my wheels feeling proud of the form of the
| project. The projects where I just threw caution to the wind
| and cut corners strategically (not everywhere, mind you) were
| the ones where I ended up shipping something.
| GordonS wrote:
| I used to feel the same way when working on solo projects,
| eschewing tests, build automation, and even source control.
|
| It wasn't tool long before source control was missed - at it's
| simplest, it acts like a backup, but having the full history is
| really useful. Once familiar with SVN (this was 15 or so years
| ago), it really didn't add any overhead at all.
|
| I thought tests would he too much work to maintain - but
| looking back, it was clear that it was my lack of experience
| and understanding that was the problem. The _way_ I was writing
| tests, laden heavy with mocks, and brittle as a result, was
| resulting in crap tests. Much later, when I 'd finished making
| terrible mistakes, but had learned a lot from the process, I
| realised how helpful tests were. I believe they are usually a
| net benefit - the number of times where I write a test for
| something that seems really simple, and it fails, is higher
| than I'd like to admit. Failing fast during dev is _far_ prefer
| to having to diagnose production issues. And it also means I
| can refactor with much more confidence. Also, for OSS projects,
| I think the presence of a good test suite inspires confidence
| in users.
|
| When working solo, the time taken for manual tasks also irked
| me - especially when preparing final releases, where I was
| anxious not to get things wrong - building for different
| platforms, creating installers, putting together configs,
| putting together docs, code signing, running things through
| Virus Total, publishing binaries... it took soooo long, and was
| error prone. In the beginning, automating this kind of stuff
| seemed like a mountain, but again with experience came
| competence and confidence. And the time savings were great, and
| the extra confidence around releases was huge.
|
| Each to their own of course, but for anything non-trivial I
| wouldn't be without source control, tests or build automation.
| twodave wrote:
| Definitely--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 wrote:
| I 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 wrote:
| Relevant 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/
|
| 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 wrote:
| FYI Git has a difftool setting/feature specifically for doing
| diffs through an external command.
| rrosen326 wrote:
| I'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.
| Semaphor wrote:
| I do the same. I use branches almost exclusively for features
| that won't be done for a while and won't make it into
| production until then.
| kop316 wrote:
| That has been my pattern for some hobby projects, however it
| quickly becomes a mess to keep track of what you have done over
| a period of time (I have the same bad habit, I commit things so
| I can freexe my code in case I mess something up).
|
| My hobby project has been to extend a program with a new
| plugin, but then along the way I found bugs in the core code,
| and I wanted to upstream the fixes (and the plugin). I am very
| glad I knew what the fixes where, becasue I more or less had to
| rebase to the original code in order to untangle the mess of
| commits I made.
|
| I have also found other folks wanting to use my code, so it
| also made it much more helpful if ourside folks can see how I
| altered the original program.
| bluetwo wrote:
| As a solo developer who works across several machines, I still
| use subversion to coordinate code. I have yet to see the
| advantage of using git in this situation.
| gmfawcett wrote:
| As long as you're not still using CVS -- that would just be
| masochistic. :)
|
| If it's working, stick with it. Most people use Git as a
| centralized RCS anyway. I like the decentralized features of
| Git (darcs, fossil, hg, whatever), but mainly for short-term
| problem solving -- on any project, eventually an official hub
| emerges.
| [deleted]
| w0mbat wrote:
| Absolutely. This guy has too many rules.
|
| When I work alone I'm climbing a mountain, and Git is the rope.
| I can fall, but I won't fall far. I commit as often as I want
| to. The log is not a story for someone else to read later, it's
| the way I get to the top.
| jeremyjh wrote:
| I find commit logs useful even if I'm the only person ever
| reading them. I like to be able to git blame on a line and be
| reminded of the context in which I did something and what I
| was trying to solve. I don't bother to pretty up my feature
| branches though, I just squash them so that master has a
| clear story
| SilverRed wrote:
| How we do it at work is every single commit message must
| have a ticket number in it. This is super easy to do and
| super useful. Even if the commit message is "fix exception
| #1823" you can go and look up #1823 and see what that issue
| was to make sure you don't reintroduce it with your change.
| You will always find more info and context in the ticket
| than in git commit messages.
| mplanchard wrote:
| This is an excellent metaphor, thank you. I'm going to add it
| to the bag of metaphors I use when explaining git
| BrandoElFollito wrote:
| > Is this a terrible coding practice
|
| It is not. I do the same.
|
| I tried to use git the way OP describes and I was taking more
| time to manage the logistics than to code.
|
| I then hit the "I can obviously call a function in a new commit
| from one in a previous one". Handling this gracefully means
| full time work.
|
| My code works 70% of the time anyway si I ended up making
| efforts to move it up a few percent points than to have a
| byzantin git tree.
| mellavora wrote:
| Some of the sophistication you are 'missing' is there as a
| solution to scaling problems, to business problems (do you need
| to track/fix customer/client issues?), or to other problems
| that _may_ not be as critical for solo devs.
|
| Some of the other is best practices which you are missing out
| on.
|
| You might want to take a look at what some 'best-practices' are
| and see which might improve your coding.
|
| Simple things like tagging a commit as
| "feature/fix/refactor/chore" might make you think differently
| about your programming workflow. Or you might find it more of a
| distraction and limitation than a help.
|
| and yes, sometimes you certainly need that 'interim' tag to
| freeze work. For those rare cases where you run out of time or
| inspiration before you get to a natural end point of a task.
| sebmellen wrote:
| For me, those cases of running out of time or inspiration
| before I get to the end of the task are incredibly common
| (basically a daily occurence). I understand it might be rare
| for you, but for me (and I would think others) it's the
| default state of programming.
|
| When I'm really getting going I flow through a ton of work
| and only stop when I hit a time limit, so I expect to finish
| in the middle of a task whenever I start coding.
| ChuckNorris89 wrote:
| I thought I was the only one using guy like this.
| tux1968 wrote:
| Rebasing private code to clean up WIP commits and break it into
| logical steps is healthy and a very good practice. But as Linus
| himself says in the linked mailing list post[1], just don't
| rebase public code. "In other words, you
| really shouldn't rebase stuff that has been exposed
| anywhere outside of your own private tree. But
| *within* your own private tree, and within the commits
| that have never seen the light of day, rebasing is
| fine." -- Linus Torvalds
|
| [1] https://yarchive.net/comp/linux/git_rebase.html
| frant-hartm wrote:
| This applies mainly to projects with kernel style of
| development. There are not many of those. In centralized repo
| style (GitHub), it's fine to rebase, even force push as long
| as you know exactly what you are doing and coordinate with
| your colleagues.
| jeremyjh wrote:
| In a lot of projects topic branches generally have a single
| owner and are not used as the basis of other people's
| branches, even if they are technically public they are not
| public in the same sense that he is referring to. If you
| aren't going to be getting PRs on your branch you can
| consider it private and rebase all you like IMO.
|
| edit to add: I generally prefer people not rebase after
| they've asked for a PR review just because the reference
| for comments will be lost. If they want to, maybe do it
| after all the reviews are approved.
| matwood wrote:
| I'm going to disagree, unless your are a solo developer
| (and even then it's bad practice to rebase commits that
| have already been pushed). Allowing rebase on shared
| branches just opens the door to too many possible
| catastrophic mistakes. When I make a new repo the first
| thing I do is disable history rewriting.
| prpl wrote:
| If using this pattern it helps to split out your commits, i'd
| possible. I do this with changelists in intellij/pycharm.
| philote wrote:
| Even when I use git by myself, I like to use branches. This
| helps me keep my work separate, and avoids issues if I'm
| working on one thing but need to do a quick fix elsewhere. I
| also tend to have anything in master set to go to live, so
| branching helps keep things that aren't ready from going live.
| Even if you don't have a "production" environment you push to,
| making sure your master branch is only code that works well is
| a good idea IMO.
|
| And as another reply mentioned, squashing commits is good for
| keeping your history cleaner. My branches tend to have a ton of
| "fix" commits that get squashed out when merging into master.
| ZephyrBlu wrote:
| Another reason I personally like branches is because it gives
| me confidence to make breaking changes without immediately
| having to worry about regressions.
| [deleted]
| matwood wrote:
| > Is this a terrible coding practice?
|
| Not at all. Copying folders with names like code1, code2, code3
| is terrible practice. Using SCM and committing as checkpoints
| while you work is _good_ coding practice. You have a process,
| and it works for you.
| lamontcg wrote:
| Yeah I'm 13,000 lines into a solo side project and haven't
| bothered with a single branch+merge. I've got a bunch of tests,
| but I don't test everything, I don't make sure every commit has
| tests. Commits are mostly checkpoints of when major feature
| achieve some kind of initial stability where I want to be able
| to diff back to last-known-working. I try to do better commits
| than "WIP" but they're something like "such and such feature
| now seems to actually work (lots of buggy edge conditions)".
| I'll throw in a lot of unrelated code cleanup that happens into
| single commits as well. I focus on moving the needle on the end
| results though and not having perfect process. Many bits of
| code that I have which work well enough don't have any tests at
| all. As I hit bugs I drill into code and fill out the tests
| that I didn't do. Simple code that is used all over the place
| and doesn't cause issues may not have any formal tests at all.
| I rarely actually bother to go back into my own git history,
| mostly I just use it like a quicksave in case I wind up dying
| at the next bossfight.
|
| I think what'll get you in trouble more than having perfect
| process is writing spaghetti code that violates separation of
| concerns. If things are separated well, you should be able to
| come back and test it easily if it causes issues. Test the
| stuff that is complicated and obviously will cause issues if
| its not perfect. Test the stuff that is found to be buggy or
| needs to be proven to be not buggy in order to track down bugs.
| Don't bother with perfectly testing everything.
|
| I've been adding a threaded AVL tree implementation lately. I
| definitely tested that extensively and did a savegame when the
| AVL tree was written and passing tests properly, and then added
| threads and did another couple of savegames. I'm going to build
| on top of that, and I need to be able to trust it without
| falling back into debugging it. I've got a Clamp01 function
| though which takes a double and ensures it is within 0 <= x <=
| 1 and I don't have that one tested. I'm pretty confident it
| works though.
| CalChris wrote:
| Yeah, I'm pretty much the same. Still, there are elements of
| the article's approach that I follow. Principle
| 2a: Every commit must include its own tests Principle 2b:
| Every commit must pass all tests
|
| But otherwise, I don't create branches. My commits are medium
| sized, one big thing, and to the trunk. My commit messages are
| at best ok.
|
| After a commit, I git --amend _liberally_. It 's never really
| clear in my mind when a commit ended and the next one starts.
| This wouldn't fly in a group.
|
| The one think I'd recommend is _Never Type git_. That 's
| overstating, but basically git's command line syntax is just
| terrible AND thus dangerous. I think my one moderate sized git
| screwup was due to the command line syntax. So now I hide (most
| of) it behind shell aliases. This guy goes a bit far but you
| get the idea:
|
| https://github.com/ohmyzsh/ohmyzsh/wiki/Cheatsheet
|
| I pull rarely enough that I prefer to type it out.
|
| Also, configure a good diff tool (although Apple seems to
| reject kdiff3 for now). And .gitignore goes without saying.
| dotancohen wrote:
| Regarding diff tools: suggestions welcome. I've used VIM's
| three-way diffs, and would prefer to stay in the CLI. But the
| Jetbrains IDEs come with a great GUI diff tool for Git merge
| conflicts. I'd love to find something comparable on the CLI.
| NortySpock wrote:
| I think what you're doing is fine especially if you're just
| coding for yourself. I'm perfectly happy with slightly more
| expressive commit messages like "LoadData appears to be
| working; still hacking away at TransmorgifyData", followed
| eventually by "stabilized TransmorgifyData".
|
| I think it's when you start syncing with other people over
| multiple days that people start insisting that a commit should
| (compile), be atomic, tested, etc. What they're really looking
| for at that point is that incoming changes be easy to
| understand and modular and possibly easy to omit if some code
| change is causing them trouble for a moment.
| scaladev wrote:
| Just squash the junk commits with rebase when you are done. It
| keeps the history clean and you have many points to revert to.
| edu wrote:
| If 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 wrote:
| Pretty 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 wrote:
| So 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 wrote:
| That 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.
| seanwilson wrote:
| Yep, small disciplined commits take valuable time. If you
| rarely revert or get other benefits from them they might be a
| net loss for you. Especially in solo projects when you can keep
| a lot of what's going on in your head.
|
| It's a bit like testing - there's a lot of posts about where
| you need them and not many discussing where you don't.
| oivey wrote:
| If you use "git add -p" it makes small commits pretty
| painless. I still like small commits in repos I work alone on
| because it makes reading the history during future debugging
| easier.
| JoblessWonder wrote:
| It is funny because I use git (and commit messages) to help
| me keep track of what I was working on since I'm a solo
| developer but also an entire IT department so coding is only
| a portion of my time. Sometimes I'll just be starting to
| implement a major feature when something else will come up
| and I'll have to put it on hold for a few days/weeks. Having
| the quick little commits helps me figure out where I was and
| helps me get back into the flow.
| japhyr wrote:
| Side conversation because I recognize your username. I've
| been playing wordoid every day since you posted it three
| weeks ago. You made a comment about having heard that someone
| scored 3000, and I think that's now in my mind as an end
| goal. I've gotten to about 1800 and can't quite let go yet.
| :)
|
| https://news.ycombinator.com/item?id=25999655
| jidiculous wrote:
| I don't think it's an antipattern if you're working by
| yourself. As you said, it's a safety net that helps your
| confidence in case something does go wrong. The only thing I'd
| recommend changing might be to make your commit messages a tiny
| bit more detailed, even for the interim commits - that way you
| know what's going on at each commit if you do have to
| eventually do a `git bisect` to hunt down a regression.
|
| Going a step further and rebasing interactively to tidy up your
| logs would also accomplish the same goal, but if it's just for
| your own eyes, it's probably not worth the time.
| stevecat wrote:
| If you work with branches, can you merge with the --squash
| option? This makes one neat commit on your default branch. You
| could even then commit without the -m option, and type a more
| descriptive multi-line commit message detailing the changes
| you've made.
|
| I only work on little solo projects and this is what I'm doing.
| It makes a very readable history, and helps me answer "why on
| earth did I do that?", but it's harder to revert small changes
| later.
|
| If I'm working with others, I try to match my committing style
| to the project.
| fiddlerwoaroof wrote:
| Squashing makes tools like git blame or emacs's vc-annotate a
| lot less useful: with small commits, I can reconstruct the
| code as it was when a particular line changed; with a squash,
| the coordinated changes are a lot less useful.
| jeremyjh wrote:
| Without squashing git blame has too much noise in it for my
| taste. I don't want to see 90 different commits in a single
| file's blame, when they were actually related to 9
| different features. If each topic branch has a reasonable
| scope then the squashed changes I think are more useful
| than each little tweak or fixup.
| SilverRed wrote:
| If you really want to do it nice, you get to the end and
| then move all of the commited changes in to the
| uncommited state and then recommit them in to logical
| steps and commit them piece by piece with well written
| messages.
|
| But at some point you are spending more time bookkeeping
| than the actual value you will get from it. If its a
| personal repo, don't bother. If you are sending a patch
| to Linus, tidy your commit messages.
| gopalv wrote:
| > It's kind like a snapshot-based local history.
|
| You can extend it to remote-history too, because git makes it
| almost trivial to create a repo that you want to work over the
| network (without a running server of any kind).
|
| I use git as a fancy rsync sometimes.
|
| I do most of my work on a remote box, but I still like to edit
| locally in an IDE, but occasionally I make a change on the
| remote side.
|
| On the remote side, I do
|
| git init --bare project.git
|
| git remote add clusterx remotebox:dev/project.git
|
| Then do a git clone on the remote box from that repo, then I
| can push changes back to that local repo and when I'm done with
| the day, I can just pull it all back to my laptop with a git
| pull.
|
| This used to be full of patch + diff + rsync in the past, but
| when you build stuff remotely and do diffs, but add new files
| to the codebase, it is so much easier to just use git.
|
| For my personal projects, I think CSS files are the most common
| things I've edited in this sort of loop - my web-app folders
| are generally just git clone --depth 1, which also takes care
| of the other loop where I edit locally and deploy to remote.
| jrochkind1 wrote:
| Is it "terrible"?
|
| If it's working for you to produce software how you need, then
| it's working.
|
| But I would say it's building up habits of using git that would
| _not_ transfer well to a multi-person team. That may or may not
| matter to you.
|
| OP's usage is interesting, I think by and large they are
| transferable to a multi-person team, they are still good
| habits, or on the _way_ to good habits or _similar_ to good
| habits with a multi-person team. The one difference is how much
| easier it is for a solo developer to "rewrite git history"
| without disrupting others, in OP we see it done with abandon.
|
| But in general the way OP is thinking about things -- what they
| are trying to prioritize how -- are things that apply to a
| multi-person team too. Keeping commit history readable, keeping
| branches cohesive, etc.
|
| Your practices are... not. Which doesn't make them terrible,
| but it means you are developing habits you'd probably have to
| revise when/if working on a multi-person team.
| sodapopcan wrote:
| Absolutely nothing wrong with this if you are developing solo.
| As suggested by a sibling comment, you can always squash if you
| are looking for a cleaner history, though this is probably
| isn't necessary if you are never going to share your code. If
| you are going to share and your important commits are clean,
| then it's easy to squash.
|
| Another good trick trick is to simply stage things to "freeze"
| them--You can then `git checkout` any changed files if you want
| to revert to the staged state. This is useful if you are in
| working state without a lot of changes but want to run a quick
| experiment before committing.
| gregmac wrote:
| > it makes me feel safer
|
| This for me is one of the biggest things I like about working
| under version control, even solo. It gives me the freedom to
| explore some crazy idea or refactor without having to think
| about the way back if it doesn't pan out. If it turns out to be
| more complex than I am willing to do now, I can stash or
| branch.
|
| If I think back to my pre-source control days, I used to leave
| commented code everywhere, or just make a full copy of the
| folder. It doesn't take long before this becomes an absolute
| mess. Copying in particular was a barrier: you had to realize
| it was necessary then interrupt your flow to do something that
| would take a several seconds. (By contrast, if you commit as
| you go - especially everytime you get to a working "checkpoint"
| - there's zero extra effort needed.)
| jonwinstanley wrote:
| Yes totally. It gives you freedom to try things you don't
| fully understand in your IDE or framework too then decide
| whether you want to revert everything afterwards.
| Debug_Overload wrote:
| Yeah, writing code without source control sounds horrible.
| Can't imagine what it must've been like for those who had to
| suffer through such time.
| ska wrote:
| We've had effective source control since the 70s, latest
| 80s; for the most part working without it was self
| inflicted.
| [deleted]
| colllectorof wrote:
| Modern IDEs often ave basic source control baked in. You
| don't even need to commit anything. I wonder whether there is
| any point in using Git for basic version control if those
| features are already available.
| majormajor wrote:
| At least in IntelliJ, I find using the local file history
| stuff painful. With explicit source control, I'm making
| specific decisions to check in known states. When I have to
| resort to the local file history stuff, there's a lot more
| of "oh, here I undo'd a typo" and so on type of things.
|
| That said, it can be a lifesaver when I didn't make an
| explicit commit, then started doing stuff, then realized
| "ok this got out of hand AND I wish I could go back five
| minutes but it's gonna be annoying."
| hinkley wrote:
| The intellij local history works best when your code is a
| raging monolith. It punishes you when you find coupling
| in otherwise uncoupled code, and that punishment is there
| whether you leave the coupling or try to fix it.
|
| One of the failure modes for people leaving a mess is if
| it's too hard to fix it they give up. So that's no good.
| dimitrios1 wrote:
| Yes: you like the interface for git already and are
| productive with it versus learning how to achieve the same
| productivity while learning the idiosyncrasies of your
| chosen IDE platform.
| hinkley wrote:
| I'm butchering something someone said here about a month
| ago:
|
| Some people cut a trail through the jungle, others just
| push the branches out of the way and expect everyone
| behind them to do the same.
| dpedu wrote:
| Committing aside, git also has stash. Many people prefer
| using one consistent tool (git) over the variety of IDE's
| equivalent features available.
| coding123 wrote:
| Most IDEs that have basic source control baked in typically
| means it has a git client and UI. I know that years ago I
| used Netbeans local history but it's a per-file history and
| does nothing to keep a set of files at a specific "save
| point" together.
| hinkley wrote:
| Exploratory refactoring turns out to be very close to an
| exercise in creative writing, as I learned one day
| accidentally from my lit major friend.
|
| Take the section you are stuck on, print it out, cut it up
| into sentences or phrases, and just rearrange them until
| either it makes sense, or you figure out where you went
| wrong.
|
| Rearranging code statements until something makes sense is
| exactly what refactoring is.
| systemvoltage wrote:
| I beg to differ.
|
| Refactoring is not merely rearranging code statements.
| Refactoring is _restructuring_ of the code starting from
| the architectural and abstract goal and then looking at how
| pieces of existing code would fit. Sometimes, that requires
| writing new code and tests. Refactoring by definition also
| means not breaking the user space.
|
| I've never heard of any serious writer printing out their
| prose and cutting it and rearranging it. That just sounds
| absurdly unnecessary to me.
| hinkley wrote:
| > code starting from the architectural and abstract goal
|
| you are either using a different definition of
| architecture or this is wrong. Refactoring is bottom up
| construction. Most of the time when I see people
| frustrated or struggling (including myself) it's because
| they have forgotten this and need to take a break.
| Groxx wrote:
| > _Is this a terrible coding practice?_
|
| Are you the only consumer of the practice? And do you like it?
| Then no, it's not terrible at all, it's useful. Git will
| function just fine for this. I do similar things with my
| "experiment" repos, they're practically "streams of thought
| saved to disk" and they contain a ton of digressions and
| occasional breakages and that's totally fine. I have zero
| complaints after several years of doing this.
|
| The major benefits to much-more-structured approaches come in
| the form of automated tooling that's really only useful when
| you have large repos or many contributors (git bisect is a
| perfect example), or external automation (ci/cd pipelines,
| etc). For those kinds of repos, yeah, I'd say it's a terrible
| practice, and it'll cause some easily-avoided pain. But even
| then: work however you like on a branch, and merge (or squash)
| when you have "good" stuff, and it generally works well.
| j7ake wrote:
| I mostly do solo work too and for me the main goal is less to
| make code readable for other people, but for code to be
| readable for myself in a year from now.
|
| I've definitely had situations when I had reverted code to a
| year back to check if there was a bug. Git was very helpful
| from that point of view.
| zeta0134 wrote:
| For my solo projects I break the "don't code in master" rule
| because there is nobody else to coordinate with, and I usually
| only work on a major idea at a time. However I still use
| branches, usually if I want to quickly test out a breaking
| change, or if I start something I don't anticipate being
| finished with in a long time, so that my master branch remains
| usable for other side tangents.
|
| The branching strategy means that it's pretty important that my
| commits are small, the brief commit message is accurate (even
| if I occasionally commit too many changes at once) and the
| description explains my train of thought. Nearly every time, I
| am communicating those changes to _myself in 6 months_ when I
| switch into that branch randomly and wonder what I was in the
| middle of doing.
| dilawar wrote:
| I do the same if I am doing assignment or writing a single
| script.
|
| I'd prefer something close to his if I am writing a library or
| a small app.
| GuB-42 wrote:
| Same thing for me.
|
| Generally I am against rewriting history unless there is a big
| mess to fix. For me, git is my work process, and bugs, typos,
| bad merges and code that doesn't compile is part of it and I
| don't try to hide it. Personally, I value historical accuracy
| more than cleanliness.
|
| But some people have compelling arguments for the opposite,
| like the author. These people tend to view git as a release
| schedule where every commit is workable code. It is good for
| bisecting, and git log is your actual changelog. But you lose
| information about how you solved problem, when you did what,
| etc... it is also more time consuming to maintain.
|
| You can use a hybrid solution with two parallel branches and
| merge commits, or you can just use tags.
|
| Git is not very opinionated on how you should work. Merge or
| rebase, clean or historically accurate, push or pull, etc...
| There is more than one way to do it.
| khalilravanna wrote:
| I don't think it's an anti-pattern but you might just need some
| sort of backup tool with incremental backups and rollback.
| Sounds like it would likely suit your needs with less overhead.
| pkulak wrote:
| I do that on shared projects too. I absolutely will not end my
| day with work that exists only on my machine, and git is a fine
| place to put it, as far as I'm concerned. I routinely make a
| branch called "phil/stash" that I will commit totally broken
| code to at the end of the day. Then I rebase/ammend it into
| shape when I'm ready to PR.
| gmfawcett wrote:
| Quite a few people are suggesting that, when it's time to share
| your code with others, maybe you should squash/rebase it to
| clean things up. That's totally up to you... but just know that
| not everyone thinks rebasing is a good idea. See [1], for
| example.
|
| [1] https://fossil-scm.org/home/doc/trunk/www/rebaseharm.md
|
| I think we often feel the urge to rebase and squash not because
| it actually makes our code changes easier to understand, but
| because it makes us feel better about ourselves. That's a red
| flag. Understanding how you got to the goal -- encoding all the
| fumbles and disoriented thoughts right in the commit history --
| that can be a genuine benefit to the reader. Who do we really
| help by pretending that we're more organized, coherent, and
| linear than we actually were?
| cesarb wrote:
| > Who do we really help by pretending that we're more
| organized, coherent, and linear than we actually were?
|
| You help the reviewer.
|
| To understand why git is the way it is, you have to
| understand the workflow of the original git-using project
| (other than git itself), the Linux kernel. Whenever someone
| proposes a change to the Linux kernel, it's sent as a
| sequence of patches. Each patch should contain a single
| logical change, and will be reviewed individually. For
| instance, suppose you want to change the way a field in a
| particular structure is stored. The first patch of your
| series might introduce a couple of helper functions to access
| the structure fields. Patches 2-5 might each change a
| separate subsystem to use the new helper functions, instead
| of accessing the field directly. The next patch changes both
| the field and the helper functions to use the new
| representation. When reviewing this sequence, it's easier to
| see that each patch is correct. And that was a simple
| example; it's not rare to have patch series with over 15
| patches, and even longer patch series are not unheard of.
| I've seen patch series which refactor whole subsystems, where
| each patch in the series was an obviously correct
| transformation, while the final result was completely
| different.
| lamontcg wrote:
| My commit history is often a descent into profane madness.
| nemetroid wrote:
| > Who do we really help by pretending that we're more
| organized, coherent, and linear than we actually were?
|
| We're helping the future reader who's reading the history
| because they want to understand why a change was made - and
| "because the author of the branch initially had the wrong
| idea" is almost never the answer they're looking for.
|
| I sometimes enjoy reading stream-of-consciousness writing,
| but most of the time (especially when reading code) I'm more
| interested in the point itself. The same applies to version
| history. It _can_ be used to tell the raw story, but there 's
| usually a more useful and interesting story to be told.
| Wowfunhappy wrote:
| As a much newer developer, the biggest problem I have with
| git is that I rarely end up _actually_ making one change at
| a time. I 'll be working on some larger thing, and in the
| process I'll notice and quickly fix a smaller thing before
| returning to the original task. This might be a typo in a
| code comment, a poorly named variable, or a block of code I
| realize is dead.
|
| I suspect this is the type of tendency which goes away with
| experience, but it makes git a lot less useful. My commits
| won't really tell you what changed; the most they can tell
| you is the _primary_ change I was working on.
| jpitz wrote:
| With the add command's interactive mode, it is often
| possible to selectively stage and commit individual
| patches in a file.
|
| https://git-scm.com/book/en/v2/Git-Tools-Interactive-
| Staging
| bentcorner wrote:
| Look at `git add -i`. You can commit just part of a
| change to a file. So if you notice a small problem and
| already have a bunch of changes made, you can still make
| those changes, and commit them separately.
|
| Up to you if you wanted to rebase those changes back onto
| main.
|
| I don't use it often and find it's kind of painful to
| use, but if you're in the position where you've already
| saved two different things in your IDE and need to pull
| them apart for commit, it's a useful tool.
| gmfawcett wrote:
| Many of us do that, and it's not just a new developer
| thing. Git actually _enables_ this, because you get to
| pick and choose what to add to the index (`git add`)
| before committing. So that little tweak you made in the
| unrelated function? -- no problem, just `git add` that
| later, and commit it under a different message. Not all
| SCM tools give you that kind of flexibility.
|
| On the other hand, there's a diminishing return to
| placing every tiny change into a separate commit. Commit
| messages like "Fixed multiple small things" might make
| some people clutch their pearls, but sometimes you just
| need to _get shit done_ and move on to solving bigger
| problems.
|
| My suggestion is to consider breaking your commit into
| two: one for "fixed this big issue that everyone cares
| about", and one for "a bunch of tiny cleanup stuff that I
| happened to notice." (Maybe call that second one
| "refactoring" -- it will go over better with your
| audience.)
| Wowfunhappy wrote:
| > Git actually enables this, because you get to pick and
| choose what to add to the index (`git add`) before
| committing.
|
| That assumes the changes are in separate files though,
| right? I know you can do use the "-i" flag, but it's
| fairly labor intensive.
| gmfawcett wrote:
| That kind of depends on your tooling. e.g., I use Magit
| (an Emacs front-end for git) which makes interactive mode
| really, really easy.
|
| (But easy or not, other version control systems such as
| Subversion don't offer the feature at all. We kind of
| take Git for granted these days, but it wasn't always
| like that.)
| FrancoisBosun wrote:
| That is what OP was talking about: after you've done the
| change, make a commit with just that tiny refactoring.
| Once you're done and ready to review your work, you can
| cherry pick just that fix and move it to main / master /
| it's own PR. Since it is self-contained, it can be
| processed by itself only.
| foldr wrote:
| Have you tried using 'git commit --patch'? It makes it
| easy to separate out unrelated changes when committing.
| You can precede it with an invocation of 'git reset
| $HASH' to restructure your last few commits.
|
| In general, more experienced git users aren't actually
| working on one commit at a time. They're just comfortable
| enough with editing history to make it look that way.
| zoomablemind wrote:
| > We're helping the future reader who's reading the history
| because they want to understand why a change was made...
|
| "Change" is a subject to interpretation. Most of the time
| it's the scope that the change belongs to is what has the
| meaningful value.
|
| Say, changes made in connection to fixing an issue are
| logically tied for inclusion as well as for potential
| unwinding.
|
| Some tangent changes technically should not be casually
| folded in, just in case this changeset will need to be
| propagated or rolled back.
|
| Thus this elaborate muli-staged commit management in Git.
|
| Many projects don't have such need to manange the change
| flow, so Version control is used as a kind of undo buffer.
| Which is fine, in such cases the meaning is tied to release
| states.
|
| If anything, it makes more practical sense to preserve only
| commits with a buildable state, not just some transitional
| changes.
| acemarke wrote:
| Exactly. I want to "tell a story" with my commits, and that
| story is really more of an idealized retelling of what I
| actually did.
|
| Five years from now, no one needs to know that I forgot to
| add that one line to a prior commit and had to add it
| separately, or that my first attempt didn't quite pan out
| as expected.
|
| What that future person _will_ care about is:
|
| - What final changes actually got made?
|
| - What task was I working on?
|
| - What was the reason for any of these changes in the first
| place?
|
| - Why did I make some of these changes specifically to
| implement that task?
|
| - What additional side info is important context for
| understanding the diffs?
| fao_ wrote:
| > or that my first attempt didn't quite pan out as
| expected.
|
| Actually that's still important, it's just important from
| an architecture perspective.
| gmfawcett wrote:
| I understand that you want to tell a story. But as
| someone examining your code, I also want to know how you
| got there. While you're throwing out your junk, you're
| also throwing away valuable information. If I'm taking
| the actual time to review the code history, then let me
| play it out in real-time, mistakes and all. I know how to
| step back and summarize, I don't need you do do that for
| me.
|
| This is especially true if your code is _clever_. I 'm
| much more likely to understand your polished gem if I can
| see all the things that you bumped into while you were
| discovering it.
| Groxx wrote:
| While I understand and somewhat empathize with this
| desire (I'd use it all the time for personal repos, for
| example)... current VCS systems are _terrible_ at
| supporting it.
|
| What you probably want in this case is something like
| "automatically commit on every change (possibly recording
| every keystroke)" + "automatically tag based on
| tests/builds passing or failing" + "allow manual comments
| at any time, whether based on files changing or not". All
| of that is _technically possible_ with git
| /hg/fossil/etc, but it's so much work for both the
| recorder and the viewer that it's infeasible.
| mathstuf wrote:
| That is what comments and commit messages are for. I
| trawl history all the time. Running into an unbisectable
| mess of a branch (because a bug that was introduced in
| commit X~15 is fixed in X on the same branch) is a
| complete nightmare. I have to discect the branch history
| and understand what is because of the branch and what is
| debugging/review/CI cycle cleanups. Commit messages for
| fixups also tend to be 100% terrible and utter trash.
| "Fix review comments". Thanks. If we're doing that, let's
| copy _what the comment was_ in too and why it fixes it.
|
| The problem with your request is that 90+% of the time
| (with the way I develop), the dead ends are on MRs that
| got closed or code that never got pushed in the first
| place. So again, comments as to why this approach is used
| is _way_ better than hiding it in the history because
| someone coming to "clean up" code _sees_ the thought
| process instead of having to remember to search for it.
| gmfawcett wrote:
| I don't do much work like that -- I suspect you're part
| of a much larger developer team -- but I think I
| understand the problem you're describing.
|
| Couldn't you simply review/bisect at the fork/join
| points? i.e., take the commits at which forks began or
| ended, ignore any intermediary commits, and run the
| bisect (or, read diffs) across that subset? That way
| you're only comparing at the chapter-markers of the
| story, so to speak, and not getting mired in the gory
| details.
| mathstuf wrote:
| Yes, `git bisect --first-parent` was a feature I wanted
| for a long time. It finally exists now, so yes that
| _helps_ , but is not a complete solution.
|
| Even with `bisect --first-parent`, I _still_ want useful
| commit messages which "fixup" commits, again, are
| uniquely terrible at being on the whole.
|
| I do software process and other things, so some of my
| branches tend to be gigantic (e.g., revamping the build
| system) and can be 200+ commits because one cannot
| meaningfully land a build system rewrite incrementally.
| That one in particular was meant to be bisectable because
| when rebasing on top of new development, I wanted fixes
| to be in the "port this library over" commit instead of
| after some random merge commit based on when I decided to
| sync up that week (it took a year to do it). So once I
| get it down to a particular MR, being able to inspect
| that topic is still a useful property.
|
| Note that this only works with a `merge --no-ff` workflow
| too. The `rebase && merge --ff-only` pattern and `merge
| --squashed` are both terrible, IME, at making useful
| history. The force-rebase workflow is just as confounding
| to me as the no-rebase workflow (the former de-
| parallelizes your MR merge process and the latter tends
| to make a terrible commit history).
|
| Note that even for single-developer projects I run, I
| tend to make PRs even for my own changes (once it's
| gotten off the ground).
| SamBam wrote:
| Exactly. It's also great to compartmentalize different
| aspects of your change.
|
| Often my changes are
|
| 1. Refactor the existing code to support the new feature
|
| 2. Add the new feature
|
| It's great to keep these separate, because someone can
| look at number 1 and see that the two versions of the
| code ought to be functionally the same (same tests pass,
| app looks the same, refactor is easy-to-understand), and
| look at number 2 and see the new feature.
|
| There are countless other times where you want to tell
| the "story" in a logical fashion.
|
| (Honestly, I expect that there is a significant
| correlation between being a good git committed and being
| a clear story-teller.)
| fiddlerwoaroof wrote:
| This is great, except that we're often bad at recounting
| this idealized history without lying in ways that make
| later maintenance more difficult
| ChrisMarshallNY wrote:
| I have found this works a charm, if I want to present a clean
| repo (for things like tutorials and classes):
| https://24ways.org/2013/keeping-parts-of-your-codebase-
| priva...
|
| But basically, I let things "all hang out."
|
| Tools shouldn't really be running the show.
| dtech wrote:
| The advantage if that you get a more usable and
| understandable list of historical changes. "You wouldn't
| publish the first draft of a book" [1]
|
| A squashed merge or rebased and cleaned set of commits gives
| a very clean overview of which changes where made, at what
| point, why they were made, and what together. That picture
| tends to get utterly lost in the "set up X", "make test Y",
| "fix typo", "wip" and "change error handling" commits a
| feature branch typically has.
|
| Additionally I'm not really interested in that my colleague
| started change X yesterday before lunch, I'm interested in
| when it went live and became visible for the all developers
| when it was merged into the main branch.
|
| [1] https://git-scm.com/book/en/v2/Git-Branching-
| Rebasing#_rebas...
| professoretc wrote:
| You wouldn't publish a first draft, but neither would you
| burn it once the final draft was off to the printer.
| Personally, I'd prefer it if "squashing" commits was purely
| a UI thing; the underlying commits were all still there,
| but grouped together and _displayed_ as a single big
| "virtual" commit. That way you could still drill down to
| the real history if you needed to.
| chrisweekly wrote:
| Pull requests can serve the same purpose; messy feature
| branches and a clean main trunk.
| JonathonW wrote:
| The only way you get that in Git is if you squash-and-
| rebase before merge, though. Which is fine if that's the
| process and end result that you want, but does (if you
| keep feature branches "messy") disconnect feature
| branches from their related merges into trunk from Git's
| point of view.
| mikepurvis wrote:
| Yeah, you're reliant on Github metadata to make those
| links for you; there's nothing natively in git itself
| doing it. It's also an all-or-nothing affair, where the
| whole PR becomes a single squashed commit. To get
| anything in between ("here's my single large PR which
| I've rebased into N incremental commits, but you can also
| dig in and see the work that actually led here"), you
| really do need first class support in the tool.
|
| I suppose the Github answer to all this would be "just
| make separate PRs", but going that way asks a lot more of
| the developer in terms of how polished those incremental
| states need to be.
| xorcist wrote:
| Why would you want to see every typo that was corrected?
| Every little test that was changed erroneously and then
| backed out again?
|
| That may be an accurate representation of the order
| savepoints were made, but it's not an accurate
| representation of how the software evolved. It is noise
| that needs to be discarded if a reader would like to know
| what change was _really_ made. It also makes if difficult
| or impossible to use tools like git bisect.
|
| Is the argument really that a more detailed history is
| always better? In the trivial case every keypress could
| be a savepoint, and every savepoint a commit.
|
| One does not always know in advance that a commit needs
| to be split in two. The only way to produce readable
| commits without rebasing them in that case is to work
| with local _backup files. A version control system does
| this much better.
| gmfawcett wrote:
| In fairness, you're only seeing 5% of the typos. We
| caught the other 95% before committing. :)
|
| I love your question, "why not a commit per keypress?",
| because it raises an interesting follow-up: why not
| squash and rebase entire _months or years_ of project
| work into single commits? If squashing is so useful, why
| do we only apply it at low-grain scales? Could we read
| and understand massive projects quickly and easily, if
| they only had a few commits to them?
|
| I'm sure that we don't _experiment_ with larger-scale
| rebases because of the limitations in the technology --
| we all know that we 're not supposed to 'git rebase' in
| public, and why that is. But suppose those obstacles were
| lifted. Now that we can rebase and rewrite at any time
| scale, which scale(s) is the right one(s) to choose?
| anaerobicover wrote:
| > it raises an interesting follow-up: why not squash and
| rebase entire months or years of project work into single
| commits?
|
| That's effectively what happened before version
| control/before the small-scale rebases we enjoy now were
| possible. And the reason is that it's hugely valuable in
| certain circumstances to be able to see some granularity
| of the history. (Though clearly people disagree about
| what the grain size should be.)
|
| > Could we read and understand massive projects quickly
| and easily, if they only had a few commits to them?
|
| I don't think so. The current state is visible at the top
| of the git tree regardless. History comes in when you are
| trying to understand _why_ the state is what it is.
| Usually this is for troubleshooting in my experience, but
| sometimes also when doing a refactor. Meaningful commit
| messages attached to meaningfully-clumped patches are, in
| my opinion, absolute gold in those cases.
| xorcist wrote:
| > why not squash and rebase entire months or years of
| project work into single commits?
|
| The argument here is that one should rebase and carefully
| craft commits that isolates each functional change into a
| separate commit, where each change is motivated and
| builds on previous, before pushing anything. Every commit
| should build cleanly, preferably even pass tests. That
| makes changes easier to reason about, and enables the use
| of tools such as bisect. Look at git itself for an
| example of this type of history.
|
| The counter argument to that was that it presents a false
| view of history. Maybe there were false starts and
| mistakes made along the way. Without preserving these to
| history the reader is left without understanding these.
| This is not an uncommon argument. Some people argue
| rebase should never be used.
|
| This view suggests that a more detailed history is
| preferable. Taken to its logical extreme, that would mean
| every keypress and editor command.
|
| But "why not delete all of history" is not an example of
| "carefully crafted commits" taken to an extreme. Quite
| the opposite.
| BeetleB wrote:
| Mercurial does this with the Evolve extension.
|
| https://www.mercurial-scm.org/doc/evolution/user-
| guide.html#...
|
| It still has the individual commits, but the interface
| will make it appear as if it's just one commit.
| gmfawcett wrote:
| The Fossil designer agrees with you:
|
| "So, another way of thinking about rebase is that it is a
| kind of merge that intentionally forgets some details in
| order to not overwhelm the weak history display
| mechanisms available in Git. Wouldn't it be better, less
| error-prone, and easier on users to enhance the history
| display mechanisms in Git so that rebasing for a clean,
| linear history became unnecessary?"
| mikepurvis wrote:
| I'm not a user of it myself, but I believe this is the
| philosophy behind how Fossil approaches it:
|
| https://fossil-scm.org/home/doc/trunk/www/rebaseharm.md
| ulisesrmzroche wrote:
| The real history is useless. Especially if we have tests.
| In that case it doesn't matter how often we make changes.
|
| I do think this is because I prefer to think of code as a
| black box. No one should need to figure out how my
| functions work. Someone should just need the name of the
| function, what inputs it receives, and what output does
| it return. If someone actually has to read my code,
| that's a failure.
| gmfawcett wrote:
| > If someone actually has to read my code, that's a
| failure.
|
| I can't tell if you're being serious, or are a brilliant
| troll. :)
|
| Assuming you're serious, Hyrum's Law is one reason I
| might need to see your code (https://www.hyrumslaw.com/).
| The signature of your function is not the whole
| signature, it's just a sketch of the high points.
| [deleted]
| ulisesrmzroche wrote:
| You really should just need to read the code in case
| something goes wrong, but otherwise, no. You need to be
| more careful with your time.
| aspaceman wrote:
| I think that's a pretty valid argument about just wanting to
| rewrite history.
|
| I'll offer an alternative. I love having every commit
| buildable. When I'm drafting, this isn't going to happen. I'd
| like to save my work and move between machines more
| frequently than that. But after a rebase, it's great to only
| have compiling commits. It makes doing a bisect a lot easier
| when you're hunting for something.
| [deleted]
| Droobfest wrote:
| Yea... 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.
| SilverRed wrote:
| The easy mode is just doing the work in another branch/merge
| request and then ticking the "squash on merge" checkbox. You
| may or may not want this depending on how important the
| individual commits are but sometimes you end up with 50 "fix
| it" commits that add no value.
| lwall wrote:
| Kind 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 wrote:
| Well 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.
| rob74 wrote:
| As long as the bugfix is at least in a commit of its own so it
| can be cherry-picked into another branch if needed, that should
| work too...
| dukeofdoom wrote:
| Just 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.
| mustak_im wrote:
| I used to do that before the introduction of docker+kubernetes.
| Once you've incorporated this into your solo workflow, you will
| never look back.
| jedimastert wrote:
| It'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
|
| 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
| matwood wrote:
| Other comments mention Docker and Kubernetes which feels like
| overkill for what you describe. Especially Kubernetes.
|
| Check out bitbucket pipelines that trigger on a commit which
| should be able to build/run any tests, copy the code to your
| server, and then restart django.
|
| From there you can later build a docker image and copy it to
| run wherever, etc...
| cashewchoo wrote:
| I 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.
| SilverRed wrote:
| Agreed, I once worked at a place that used saltstack to
| manage rails servers and it would take me an entire day to
| set up a new server with the tools it needs and getting the
| app running. Now with docker its so trivial to get something
| running on the server and even multiple versions of ruby for
| different apps.
| twodave wrote:
| Most 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.
| yummybear wrote:
| You 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...
| moosebear847 wrote:
| Anyone 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..
| WorldMaker wrote:
| Perhaps 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.
| sebmellen wrote:
| Perhaps 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.
| MaxBarraclough wrote:
| I'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
| ctb9 wrote:
| Ten 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 wrote:
| I 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.
|
| There's also just "meta" which is a cleaner way to approach
| the functionality of submodules
| https://github.com/mateodelnorte/meta.
| PeterWhittaker wrote:
| I've some ideas based on recent work, but I want to make sure I
| understand your use case: should changes to A and B be
| independent, but A and B require each other to do useful work?
| twodave wrote:
| The "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.
| olav wrote:
| Some 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/
| dmitryminkovsky wrote:
| When 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.
| symlinkk wrote:
| What's the point of using the reflog? Just make multiple
| commits instead of amending a single one
| froseph wrote:
| I 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.
| mustak_im wrote:
| This 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.
| tonymet wrote:
| Git 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 wrote:
| When 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 wrote:
| +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 wrote:
| I 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.
| tpmx wrote:
| Git 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 wrote:
| git 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 wrote:
| I 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 wrote:
| Learning 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
| SilverRed wrote:
| >The crux with git is that you really do have to learn it
| in depth
|
| You don't though. I was using git for years at a 2
| developer shop and I don't think I used anything but
| commit, pull, push, add. It was very trivial, never even
| made a branch.
|
| Then when I moved to a bigger place I had to learn about
| cherry-pick, revert, reset, bisect, checkout, etc but every
| single one of those things I learned was immensely useful.
| offtop5 wrote:
| You can use GitHub when you're getting started.
|
| I found get to be an extremely useful tool when I needed to
| go back and look over some of the changes I made.
| tpmx wrote:
| No, that doesn't help much in understanding git to the
| level that you're self-sufficent.
| offtop5 wrote:
| It's enough to back up your work and send the code to
| potential employers
| acemarke wrote:
| Heh. 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-...
| strzibny wrote:
| This is a good idea how to do git in a team. For solo use, you
| can actually give yourself a little bit more slack.
| pizza234 wrote:
| I 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 wrote:
| This comment reminds me of writing structured articles: writing
| structures your thinking. I guess having things in a clear
| workflow does the same thing.
| freedomben wrote:
| I 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!
| sillycube wrote:
| As a solo founder, I only use git add, commit, push, pull, clone.
| That's all I need
| PeterWhittaker wrote:
| Whether 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.
| Ericson2314 wrote:
| My very first programming project, porting
| 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!
| yters wrote:
| One 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.
___________________________________________________________________
(page generated 2021-02-23 23:01 UTC)