Search code examples
gitproduction-environmentgit-clone

git: Copy a version for playing around


While developing an application, I would like to have at one point a separate copy of my work for experimenting with several changes. Theses changes are not meant to be committed! It's just playing around, to try out various possibilities.

What is the "best" way to do this? I found the following possibilities, but would like to get the advice of people who have more experience with git than I do:

  1. I could use git clone to get a copy of the repository into a different directory, and use it to play around.
  2. I could just cp -r my current git working directory to the new one.

In case (1), git is aware about the clone, and I could later rebase if I really would want to, but it is unlikely that I will ever do this.

In this case, is there something I should be aware of, which makes either solution (1) or (2) preferable? Or is there an even better way to do it?


Solution

  • TL;DR

    Using a clone/copy

    • pros: main repo and its clone/copy are complete silos
    • cons: space inefficiency

    Using a branch

    • pros: space efficiency (Git branches are cheap)
    • cons: relatively unwieldy workflow if a lot of stashing is required

    Details

    You write

    I would like to have at one point a separate copy of my work for experimenting with several changes. [...] What is the "best" way to do this?

    You also write in your comment that you're likely to switch back and forth between the original work and its "copy", without committing any changes carried out in the latter.

    You have different possible approaches, here; let's review your two suggestions first, and then explore a third possibility. To fix ideas, I'll assume your repository lives in a directory called main.

    1 - Use git clone to get a copy of the repository into a different directory, and use it to play around.

    As you suggest, you could produce a clone of main, say, into a directory called exp,

    git clone <path-to-main> <path-to-exp>
    

    and conduct your crazy experiment in exp. The main repo would be exp's "upstream", i.e. exp would list main as one of its remotes under the name origin. Therefore, if you made more commits in main and wanted to keep exp up to date with what's going on in main, you could fetch from main to exp and then merge or rebase in the latter.

    The main problem with this approach is space inefficiency: because a clone carries the entire history of the original repo with it, you will get a lot of duplicate files on your disk. That may or may not be a problem, depending on the size of your original repo, but it's something to consider.

    2 - Just cp -r my current git working directory to the new one

    That's essentially like cloning main but, unless you manually add main as a remote of exp, you won't be able to fetch from main to exp. I don't see any advantage in this approach compared to the first one (except, perhaps, that it doesn't involve the risk of accidentally pushing stuff from exp to main).

    3 - Create a new branch directly within your original repo and conduct experiments in it

    A third approach is to create a new branch (let's call it exp) directly within your main repo,

    git branch exp
    

    check it out,

    git checkout exp
    

    and conduct your experiment in there. The main advantage of this approach over the other two is space efficiency: Git branches are cheap, in that creating a new one doesn't involve any copying of files.

    However, if you make changes while exp is checked out but do not commit them, Git will deem your working directory "not clean", and won't allow you to switch back to your master branch until you remedy the situation. One possibility for cleaning your repository is to stash your uncommitted changes, by running

    # while on exp, if there are uncommitted changes
    git stash save
    

    You could then switch back to master, do some changes, commit them, switch back to exp, and retrieve your stashed changes by running

    git stash pop
    

    If a lot of stashing (save and pop) is involved, though, you may find this workflow too tedious and unwieldy...