9

I made some changes that, after testing, I decided not to use for now. Thus I don't want them in the main branch. However, I don't want to discard them altogether (maybe I will need them later?)

What should I do?

The easiest option is to commit them and immediately revert (don't laugh).

I suspect that what I am supposed to do is to create a separate branch, commit there and not merge into main. However, I have never used branches before, so I am reluctant to start if there is a simpler option.

PS. I am the only person who is using this repo, and this is unlikely to change.

7
  • 16
    if you are the only person using the repo, it probably doesn't matter how you do it
    – Ewan
    Commented Jan 3 at 18:50
  • 2
    This is what "git stash" is for.
    – pjc50
    Commented Jan 4 at 9:30
  • 57
    Learn to use branches Commented Jan 4 at 12:53
  • 17
    @pjc50 "git stash" alone will just store things away locally. It won't get added to the repo, much less pushed upstream. It's appropriate for very short-term storage of unwanted changes, but if OP may "need them later", then this is probably not the right option.
    – jcaron
    Commented Jan 4 at 15:24
  • 3
    “I suspect that what I am supposed to do is to create a separate branch, commit there and not merge into main. However, I have never used branches before, so I am reluctant to start if there is a simpler option.” Branches are the simplest option that does exactly what you describe. Commented Jan 5 at 21:04

11 Answers 11

27

Although the question is different, much of my answer about what to do with abandoned branches applies to this as well.

You say that maybe you will need the changes later. How sure are you that you'll need them? How much later? Assuming that the work will be relevant later, how do you know that the way you did the work will be relevant later?

Personally, I would discard the work. You gained knowledge and experience by doing it once. If and when it comes up again, you'll be able to reevaluate the requirements and build upon your experience to develop a solution.

If you do decide to keep it, then I would commit to a branch, push that up to a remote, and set an expiration date after which you'd delete the branch because the rest of the system has continued to evolve and it no longer serves as a reliable reference for a potential solution to a problem.

15
  • 8
    +1 for the emphasis on bitrot. It's a natural reflex to not wish to discard the product of one's efforts, but said product is less and less relevant as time passes. Commented Jan 4 at 8:06
  • 9
    @MatthieuM.: The bitrot argument also applies to branch history — but part of the point of version control is that it’s extremely useful to retain history for long-term reference, so long as it’s cleanly organised to avoid clutter. Like OP, I’ve often had other material that I wanted to retain discreetly just like branch history, but hadn’t been merged to an active branch and so wouldn’t naturally appear anywhere. Commented Jan 4 at 11:48
  • 1
    @PeterLeFanuLumsdaine I don't see how bitrot applies to the "real" history of a system. There's a difference between versions of the system at various points in time (demos, releases, deployments to different environments) and a state of the system that was rejected by not integrating the changes. Maintaining the real history has value to understand the evolution over time (and, in some cases, to meet regulatory or contractual requirements). Maintaining unfinished or rejected work doesn't have as much value, especially once you can't easily integrate that work.
    – Thomas Owens
    Commented Jan 4 at 12:00
  • 3
    @PeterLeFanuLumsdaine I don't see how the code would be useful. The only code that matters is what was actually implemented. If you want to capture information, perhaps consider an ADR. ADRs typically include rejected options and why you rejected them, and if you use textual formats, ADRs are something that you can include with the commits. So when you merge your final implementation, you would also be merging the associated automated tests and the ADR and perhaps make that traceable to an issue in your issue tracker that has even more information.
    – Thomas Owens
    Commented Jan 4 at 14:33
  • 4
    Deleting commits is just stupid, you never know in advance if the code will be useful. It may be unlikely, but it's also essentially without cost to keep them as proper commits. ADRs or expiration dates for a branch are more complicated solutions that don't solve any actual problem, the git history can already do everything required here. Bitrot is not an argument, it's clear to everybody that something that happened why back in history can't be directly applied to the current codebase, but that doesn't mean it's not useful. Commented Jan 5 at 16:53
15

TL;DR - Spent some time learning your tools (Git specifically).

There are good tutorials for git available and you can probably pick up enough to be comfortable using branches in less than 1 hour. I am assuming/recommending that when you work through the tutorial you do so in a new repository (so that you don't impact your current production code/repository).

Keeping the code in your repository clean is important - it's another form of technical debt - if the repository is clean it is easier to follow what happened in the past.

However as long as you make time to do the cleanup before you git push it's not all the important when you commit - I make a lot of commits as I am working, with comments indicating what changes I made. Then before I push I clean up my history using git rebase and push a sanitized history to other developers.

Edit per the comment:

If I was in this position, I would just create a new branch and commit the code there, after a week if I found I didn't need it I would delete the branch.

Locally, I don't think it really matters where you put it (commit to new branch, stash, commit+revert or just throw the code away) if you are going to do a cleanup before you push it, it’s simply a matter of whatever workflow works best for you.

However, if I wanted others to view the code then having it on a separate (pushed/remote) branch makes it clear that this is something you considered, but choose not to move forward with.

1
  • 10
    So where should they keep their code? I don't understand how this answer addresses that.
    – mkrieger1
    Commented Jan 4 at 9:46
6

No there is no simpler option than using a separate branch if you want to exclude code from main branch.

It's trivial, really:

$ git stash
$ git stash branch scratchpad

Now you moved all useless code into separate branch called scratchpad which you can delete anytime without affecting your main branch. You can also use stash but unlike branches, it's not meant to be used as long term storage, it's about as reliable as keeping data in your recycle bin.

6

The easiest option is to commit them and immediately revert (don't laugh).

I suspect that what I am supposed to do is to create a separate branch, commit there and not merge into main.

These are both perfectly good options. If you want to make relatively sure you never lose access to that code then yes commit and immediately revert. That also means you can write an explanation of why you're choosing not to use that code in the commit message when you revert. When you do git blame on the relevant files you will see the reference to the reversion.

If you want the code to be a bit more out of the way and not part of the main history of your project then put it on a separate branch. It's possible at some point that branch will be deleted or someone will get a copy of your code that doesn't include that branch.

Another option is to use a git tag. Tags are like branches but while a branch is intended for work in progress and is frequently updated, tags are intended for finished things or snapshots of particular points in history and are not automatically updated in the same way.

3

This is just a special case of what to do with branches you've abandoned - I'd highly recommend to make those experiments on separate branches (branching is cheap in Git).

Your intuition of committing and immediately reverting is good, but for me this is too permanent, considering that it becomes part of the project's history although it never was an active part of it.

Git has a concept for fixed immutable code revisions: tags.

If you've used a branch, just follow the instructions in my other answer; if you don't want to use a branch, you would commit, tag, and then reset the current branch to the previous commit.

$ git commit -m "never worked reliably"
$ git tag archive/frobnicator-experiment
$ git push origin archive/frobnicator-experiment
$ git reset --hard HEAD^

This way, the code can still be referenced through the tag, but it's not part of the current branch's history.

3
  1. Switch to a new branch

    git checkout -b experiment
    
  2. Commit the changes

  3. Revert the changes

  4. Merge the branch into master, avoiding a fast-forward so that there will be an actual merge commit.

    git checkout master
    git merge experiment --no-ff
    

The result will be this history:

... A ── B ──────────── C ── D ... ─master
          ╲            ╱
           idea ── undo ─experiment

Advantages:

  • The addition and deletion are clearly grouped together, and can still easily be referenced.
  • There is a continuous history skipping the whole experiment, with an empty diff between B and C.
  • There are no unmerged branches to be kept around. The experiment branch can be deleted without losing the commits.

In fact it's even possible to omit the undo commit, and instead merge from idea directly without actually including the changes. This would however be confusing, since it will look like the changes were taken into master and only the diffs would show they weren't.

2

It depends on how big the chance is that you are going to use the code later.

If it’s like a risky refactor that you just dont want to apply in this period but for 99% you would do that later and the code doesn’t need to touch a lot of other code I would sort of “feature flag” it and already submit it.

It favors “discoverability” of this change that you still need to implement above “the proper way”.

But depends a lot on the change and your tools. I don’t mind dead code in my C# projects.

I even leave commented out code for a while after a refactor so if something weird shows up I can more easily see the mistake that I made as it is right in front of my eyes instead of behind two clicks.

I know it’s a controversial opinion but I maintain two very large projects on my own with 100.000’s of users. Everyone works differently! Come fight me!

1

You could always make a fork of the main repository, and use that for whatever POC or throwaway code you want to keep out of your main one. You can use git locally to sync from separate remotes in a single clone - ie pull/merge in the code from your fork if after some time you decide you actually want it in your main, and push that to your main remote. Most repository hosting (Github, BitBucket, etc) have mechanisms for creating pull requests or merges between forks of a given project, and you can still use any branching or testing strategy you need.

2
  • 1
    This is definitely not simpler than making a branch, and even making a branch is something OP was hesitant to do due to complexity and unfamiliarity. Commented Jan 4 at 21:59
  • All true, but it's a valid option nonetheless. I don't assume people can't learn how to do things if they want to.
    – Derek
    Commented Jan 5 at 2:23
1

I found myself simultaneously agreeing and disagreeing with the accepted answer, so I took a day to collect my feelings and write my own answer.

On the one hand, I don't think that erasing the code altogether is a good idea. On the other hand, keeping outdated code that is not going to be documented nor maintained, that is going to remain on a forgotten branch and that no one is going to dare touch because they don't remember why it's there and don't know what it is, that is going to pollute your workspace, and that is not even going to work anymore because too many other things have changed around it, doesn't sound like a good idea either.

So if you want to keep this code, I think a branch on a git repository is not the right place.

Instead, I suggest writing a journal. Make an entry for this piece of code. Detail the problem that you were trying to solve when you wrote this code; write why you wrote the code this way and not another way; and write why you ultimately decided to abandon this code and not integrate it in the main project.

Make sure to mark the date and add relevant keywords, so that you can find this entry again in the future if you need it.

If you ever find yourself working on a similar problem in the future, you should be able to find that entry in your journal, and the accompanying explanations will help you decide quickly whether a similar approach might work on the new problem or whether the reasons-to-abandon-this-code still apply.

1

Firstly, it's worth learning about Git branches and how to use them. At the very least, you should learn how to create them and commit code to them. You can learn later how to merge, rebase and cherry-pick if required.

The problem you will have is how to manage those experiments in the long term. Depending on what you do, you may find some of these experiments useful much later (possibly years).

Experiments may be abandoned in your project, but the main goal is to keep track of what you've learnt.

In an ideal world, you'd write a small, separate project that's a proof of concept for what you were trying to do. You may even want to explain everything in a blog/wiki associated with the project.

That should generally be your preferred option, but that may require time that you don't have. I'm guessing that if you (or someone else) has decided to give up on that experiment, it's because there were other constraints that pushed you to work on something else as a higher priority. At that stage, spending a few hours writing nice notes might just not be an option, unfortunately.

Also, there might be some benefit in keeping the experiment in the context of the full code at the time, even if your main branch evolves into something completely different later. (At the very least, you might be able to run that old proof of concept at a later date to remember what you were trying to do, what worked and what didn't.)

The main problem is that keeping old experimental branches in the long term can become messy to manage.

There are a few things that can help:

  • Define a convention to name those branches. That's essential. You could a prefix like experiment_. You could maybe even put a date in that name (e.g.experiment_20240105_feature_X), although that date may vary later.

  • The main subsequent problem is that you might not want to see all of these branches in your working tree or your main remote repository.

    • To address this, you can create a second remote repository where you push those experimental branches.
    • That way, you avoid polluting the main remote repository used by your co-workers and yourself, but you can keep that old code. Tools like GitHub and GitLab can help there if you just want to browse those experimental branches later.
    • You can also delete those experimental branches in your local Git repository.

All this said, if you're going to use experimental branches, try to have commit messages that are reasonably meaningful, more or less as if they'd been intended for your main branch. Avoid messages like "Trying something else...". If you can spare the time, tidy up those experimental branches (e.g. squash what belongs together) before pushing them to your experimental repository.

Long-term storage of experimental branches can be useful, but you still want to give the reader (including your future self) a chance to understand what was going on (as you should with any code).

0

Put it in a folder or file called "deadcode"

This is not an existing convention as far as I'm aware but it's something I do for personal projects. Sure if I stash or commit the code it's somewhere in git but I'm not recovering old code often enough that I have a streamlined workflow to do it. Add to that the fact that I'm liable to misremember what the old code was and potentially go through that process of digging up something other than what I needed.

So now if I consider some piece of code non-trivial enough that I might conceivably reuse it or reference it in the future but I don't want to worry about compiling / linting, I'll just comment it out and stick it in some "deadcode.kt", "deadcode.go", etc. file.

If it's your repo and you're the only one working on it, then do whatever works for you!

1
  • 1
    I agree. It depends on how big the chance that you are hoing to use the code later. If it’s like a risky refactor
    – Dirk Boer
    Commented Jan 5 at 20:32

Not the answer you're looking for? Browse other questions tagged or ask your own question.