Convert a Git working directory to a bare-like repository?

296 views Asked by At

Our development environment uses multiple repositories as part of an overall build system. The build dynamically adapts depending on which repositories you have checked out: if you don't need to build a particular component, just don't clone it.

However, once you have cloned a component, removing it from the build is problematic:

  • You can delete the files in the working directory, but git status will show uncommitted changes
  • You can delete the repository, at the expense of re-cloning when you need it again
  • You can move the repository, but your multi-repo tools might "helpfully" re-clone

Is there a better way to remove the working directory's files? Something akin to hg co null or p4 sync ...#none?

3

There are 3 answers

0
Syeberman On BEST ANSWER

After finding similar questions that didn't quite do what I want, this article provided the answer: create an empty branch.

git checkout --orphan empty
git rm -rf .
git commit --allow-empty -m "An empty working directory"

Of course, ensure you've committed any important files to your repo first. I've called this branch empty, but you can give it any name via the checkout command.

Once set up, you can switch to any branch to get your files back:

git checkout master

When you need to "remove" the working directory, commit your changes, then run:

git checkout empty

This removes all tracked files. If you also need to remove untracked files and directories, follow this up with:

git clean -fdx
4
UpAndAdam On

git clean can be used with various arguments to remove items that aren't checked in and committed, and sounds like a much better option than anything you came up with above. Creating a new branch seems completely counter intuitive as does committing false changes that erase things just to be restored separately.

For many of my own CI build scripts I do use something like this to make sure the build area is 100% pristine to what git has for it: git clean -f -x -d

However upon further reading, the confusing nature of your problem becomes slightly more evident. It sounds like you have multiple seperate repositories in a common folder and your 'build' process separately uses them all for various things.

I could come up with two obvious ways to address the problem:
1. Subtree merging : Create a repo/branch whose sole purpose is for you to subtree merge the desired versions of other repos in together so that you have a repeatable build
2. Use symlinks to the repos in your 'build' directory so that you can blow away symlinks to repo's that you don't want taking part in a given build without blowing away the repo's existence only to be recloned later.

3
Greg Hewgill On

You can use the --assume-unchanged feature:

git ls-files big-unused-component | xargs git update-index --assume-unchanged

Then, you can remove your files:

rm -rf big-unused-component

The first command lists all the tracked files in the big-unused-component directory, and then update-index --assume-unchanged sets the "assume this file is unchanged" bit in the Git index. Then, when you remove that whole directory, Git doesn't consider that a change.

To undo the effect of the previous command, repeat it with --no-assume-unchanged. The git ls-files -v command can show you which files have been ignored in this way.