Back

Git is my buddy: Effective Git as a solo developer

313 points173 comments8 hours agomikkel.ca
by rrosen3268 hours ago

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.

by gregmac5 hours ago

> 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.)

by hinkley4 hours ago

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.

by systemvoltage2 hours ago

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.

+1
by hinkley2 hours ago

> 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.

by Debug_Overload4 hours ago

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.

by ska4 hours ago

We’ve had effective source control since the 70s, latest 80s; for the most part working without it was self inflicted.

by colllectorof5 hours ago

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.

by majormajor5 hours ago

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."

by hinkley4 hours ago

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.

by dpedu3 hours ago

Committing aside, git also has stash. Many people prefer using one consistent tool (git) over the variety of IDE's equivalent features available.

by dimitrios15 hours ago

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.

by hinkley3 hours ago

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.

by coding1234 hours ago

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.

by jonwinstanley5 hours ago

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.

by gmfawcett7 hours ago

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?

by nemetroid7 hours ago

> 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.

by acemarke7 hours ago

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?

by SamBam7 hours ago

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.)

+2
by gmfawcett6 hours ago

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.

by fiddlerwoaroof6 hours ago

This is great, except that we’re often bad at recounting this idealized history without lying in ways that make later maintenance more difficult

by fao_5 hours ago

> 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.

by Wowfunhappy5 hours ago

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.

+1
by gmfawcett4 hours ago

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.)

by bentcorner3 hours ago

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.

by solraph47 minutes ago

`git add -p` will take you through all the changes in your files, and let you add them selectively. I find this makes for much cleaner commits.

by jpitz3 hours ago

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

by FrancoisBosun4 hours ago

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.

by foldr4 hours ago

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.

by zoomablemind5 hours ago

> 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.

by cesarb4 hours ago

> 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.

by dtech7 hours ago

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...

by professoretc7 hours ago

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.

+1
by xorcist5 hours ago

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.

by gmfawcett7 hours ago

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?"

by mikepurvis7 hours ago

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

by BeetleB4 hours ago

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.

+1
by chrisweekly6 hours ago

Pull requests can serve the same purpose; messy feature branches and a clean main trunk.

+1
by ulisesrmzroche7 hours ago

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.

by ChrisMarshallNY5 hours ago

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.

by lamontcg3 hours ago

My commit history is often a descent into profane madness.

by aspaceman4 hours ago

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.

by zeta01346 hours ago

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.

by tux19685 hours ago

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
by frant-hartm5 hours ago

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.

by jeremyjh4 hours ago

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.

by matwood2 hours ago

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.

by w0mbat6 hours ago

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.

by jeremyjh4 hours ago

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

by SilverRed2 hours ago

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.

by mplanchard6 hours ago

This is an excellent metaphor, thank you. I’m going to add it to the bag of metaphors I use when explaining git

by jrochkind14 hours ago

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.

by philote7 hours ago

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.

by ZephyrBlu6 hours ago

Another reason I personally like branches is because it gives me confidence to make breaking changes without immediately having to worry about regressions.

by Groxx1 hour ago

>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.

by CalChris2 hours ago

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.

by dotancohen1 hour ago

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.

by gopalv6 hours ago

> 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.

by GuB-422 hours ago

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.

by seanwilson7 hours ago

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.

by japhyr6 hours ago

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

by JoblessWonder6 hours ago

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.

by oivey7 hours ago

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.

by BrandoElFollito1 hour ago

> 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.

by stevecat6 hours ago

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.

by fiddlerwoaroof6 hours ago

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.

by jeremyjh4 hours ago

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.

by SilverRed2 hours ago

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.

by Ajedi327 hours ago

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.

by rrosen3267 hours ago

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.

by kop3167 hours ago

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.

by matwood2 hours ago

> 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.

by lamontcg3 hours ago

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.

by bluetwo5 hours ago

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.

by gmfawcett5 hours ago

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.

by NortySpock7 hours ago

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.

by pkulak6 hours ago

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.

by j7ake5 hours ago

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.

by mellavora7 hours ago

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.

by sebmellen7 hours ago

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.

by kop3167 hours ago

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.

by sodapopcan7 hours ago

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.

by jidiculous7 hours ago

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.

by Semaphor7 hours ago

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.

by scaladev8 hours ago

Just squash the junk commits with rebase when you are done. It keeps the history clean and you have many points to revert to.

by edu8 hours ago

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.

by khalilravanna6 hours ago

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.

by dilawar5 hours ago

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.

by prpl7 hours ago

If using this pattern it helps to split out your commits, i’d possible. I do this with changelists in intellij/pycharm.

by ChuckNorris898 hours ago

I thought I was the only one using guy like this.

by zippergz7 hours ago

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.

by GordonS6 hours ago

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.

by allenu5 hours ago

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.

by at_a_remove7 hours ago

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.

by twodave7 hours ago

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.

by dmitryminkovsky7 hours ago

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.

by froseph5 hours ago

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.

by symlinkk3 hours ago

What’s the point of using the reflog? Just make multiple commits instead of amending a single one

by dmitryminkovsky56 minutes ago

Writing commit messages for checkpoint commits is a drag and doesn't provide value for me. Much prefer just to amend and use the reflog whenever I (rarely) need to look at work-in-progress history.

by remram6 hours 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.

by Droobfest7 hours ago

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.

by lwall7 hours ago

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.

by Droobfest7 hours ago

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.

by SilverRed2 hours ago

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.

by rob747 hours ago

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...

by twodave7 hours ago

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.

by bogwog7 hours ago

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.

by cashewchoo6 hours 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.

by warmwaffles6 hours ago

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.

by PeterWhittaker3 hours ago

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.

by olav5 hours ago

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/

by Sodman5 hours ago

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.

by antipaul7 hours ago

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.

by WorldMaker7 hours ago

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).

by SilverRed2 hours ago

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.

by pizza2347 hours ago

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.

by mettamage7 hours ago

This comment reminds me of writing structured articles: writing structures your thinking. I guess having things in a clear workflow does the same thing.

by freedomben6 hours ago

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!

by phailhaus7 hours ago

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.

by nine_k7 hours ago

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.

by paledot3 hours ago

Nothing says "readable history" like 1000 lines in a single commit.

by mustak_im5 hours ago

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.

by dukeofdoom7 hours ago

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.

by matwood1 hour ago

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...

by cashewchoo6 hours ago

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.

by SilverRed2 hours ago

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.

by jedimastert7 hours ago

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

by mustak_im5 hours ago

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.

by twodave7 hours ago

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.

by tpmx4 hours ago

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.

by offtop54 hours ago

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.

by tpmx4 hours ago

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.

by SilverRed2 hours ago

>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.

by offtop53 hours ago

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.

+1
by tpmx3 hours ago

No, that doesn't help much in understanding git to the level that you're self-sufficent.

by golemiprague3 hours ago

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

by tonymet7 hours ago

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 )

by moosebear8477 hours ago

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..

by WorldMaker7 hours ago

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.

by sebmellen7 hours ago

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.

by ctb97 hours ago

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.

by sebmellen6 hours ago

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.

by MaxBarraclough6 hours ago

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

by PeterWhittaker3 hours ago

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?

by moosebear8471 hour ago

While mid-reply and defining what the problem is, I realized a solution would be to just ignore the nested git project B, and deal with them separately. I must admit my original question wasn't well thought out, as I can't recall why it was important that there be a relationship between A and B at all, even if they are of the same project.

Mid-reply context preserved below.

----

I have a git-inited folder A, called 'Build my web app'. Inside it, it has non-source-code stuff like pictures, pdfs, notes. Also inside it is a folder B, called 'my-web-app-js', which is source code.

[Problem was that making a commit in project B would trigger unexpected changes in A]

by yummybear5 hours ago

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...

by acemarke7 hours ago

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-...

by yboris7 hours ago

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!

by remram6 hours ago

FYI Git has a difftool setting/feature specifically for doing diffs through an external command.

by Ericson23146 hours ago

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!

by strzibny5 hours ago

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.

by yters5 hours ago

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.

by sillycube7 hours ago

As a solo founder, I only use git add, commit, push, pull, clone. That's all I need