Reputation: 1487
Here is the situation I'm facing:
A directory full of generated files where commited to the repo by mistake. They obviously shouldn't have been, so I want to remove them:
$ git rm --cached foo/*
$ cat > foo/.gitignore
*
!.gitignore
$ git add foo/
$ git commit -m "Ignored stuff in foo"
This almost solves it, but leaves a different problem. When I want to git fetch && git checkout
on the production server, all the generated files in the foo/ directory will be removed. Is there some magic I could do about it on either side? Please not that simply ignoring them is not an option as they can be changed.
Upvotes: 3
Views: 2918
Reputation: 10250
The accepted answer seems like it would work in some cases, but didn't seem like a perfect fit for what I was trying to do, so here's another approach:
I'm trying to keep track of what files some software generates, and so I'm committing various things into a git repo that I don't ever intend to share, just to see what's there.
Some files are created that are labeled as temp. I want to capture them in git, but mostly, I want to ignore them, and not track changes regularly (but be able to, if I want to), so, I wanted to create a branch with-temp-files
, check the files in there, but then not get rid of the files when switching back to my main
branch, where I'd then add a .gitignore
to ignore them while I'm on main.
When doing the git reset
, I was just going resetting to main
-- there is no origin
(or any other remote), so that didn't make sense. And I'm wanting to keep a branch that has the files, I just don't want them on my main branch.
git add temp
-- add the extra filesgit commit
-- get them into the repogit branch with-temp-files
-- now create a new branch on the commit that has the files added, but don't switch to it.git reset HEAD^
-- reset main to back before the new commit, leaving with-temp-files
as its own branch. The working tree is left alone (the files are still there, now again in an untracked state).abc123
def456
(though it could be indirectly referenced with something like origin/main
).git branch with-files abc123
or git tag with-files abc123
(changing with-files
to any name you desire)git reset def456
to go back to a state before the files were added. Without other arguments (e.g. --hard
, which would remove things -- not what we want here), the reset should leave the new files in the worktree.Hopefully this adds some additional insights for anyone else trying to work through similar situations.
Upvotes: 0
Reputation: 1323943
You can try a:
git fetch
git reset origin/master
git update-index --skip-worktree foo/*
git checkout --
The checkout should ignore the folder foo
because of the git update-index
command.
Upvotes: 2
Reputation: 1487
Not sure this is the best way to do this, but I did it with this little hack:
The commit part is what I wrote in the question, the checkout is the tricky one:
$ git fetch
$ git checkout origin/master && \
git log HEAD^..HEAD --summary --diff-filter=D \
| grep delete | awk '{print $4}' | xargs git checkout HEAD^ -- \
&& git reset HEAD
This way I checkout the latest commit in master, checkout everything that was deleted in the latest commit and then reset to HEAD so the deleted & checked-out file would be unstaged.
It works, but I still would like to see some nicer way for this for the next time this happens.
Upvotes: 0