anneteka
anneteka

Reputation: 55

Keep deleted files on git pull

In the couple of the commits I need to pull there are a couple of deletions. Those files belong to some basic project files that shouldn't be present in git repository (that was our mistake in the first place, yeah). So I am afraid that the deletion of that files might cause some malfunctioning and I don't want to spend time fixing it.

I am looking for something like

git rm --cached

That deletes file from the remote repo but leaves in local

And I need something like

    git pull --cached

that won't delete local files but will remove them from tracked files

Upvotes: 0

Views: 671

Answers (2)

cinnamonoatmeal
cinnamonoatmeal

Reputation: 126

I have an update to the answer from @phd on how to do this. Thought I'd share since it took me hours of troubleshooting to do what I was trying to accomplish and it could be helpful to other people that come across this.

I had a situation where I needed to delete a LOT of previously tracked files from the remote repo but wanted to keep those files locally for any developers that had already checked out the version of the repo where those files were tracked. What made this worse is that these files were in multiple directories, subdirectories and a few individual files in the root directory.

The main issue was that the commit where the files were deleted was NOT the last commit made to the repo. It was a few commits back.

This solution lets you use any commit to do the same thing so you aren't just limited to the last commit. This answer combines a some blog posts and other Stackoverflow answers

  1. Pull from the latest version of the branch (e.g. git pull origin master)
  2. Git checkout the commit right before all of the files were removed from git (e.g. commit_hash_right_before_files_were_deleted)
  3. Get the difference between the list of files in the current commit vs the list of files that were deleted in the commit where all the files were deleted (e.g git log --diff-filter D --pretty="oneline" --name-only --format= -l 0 commit_hash_right_before_files_were_deleted..commit_hash_where_where_files_were_deleted)
  4. Convert that list into the sed command to remove empty lines (e.g. sed '/^$/d' Got that from here: https://waylonwalker.com/git-find-deleted-files/#git-reflog-diff-filter)
  5. Pipe that list to the Zip command to zip all of those deleted files up into zip file (e.g. sed '/^$/d' | zip deleted-files.zip -@ . The sed command removes blank empty lines from the output. Got that from here https://superuser.com/a/1228717/1247351 )
  6. Switch back to the branch (e.g. git checkout master)
  7. Unzip the deleted files zip file (e.g. unzip deleted-files.zip)
  8. Reset the list of files to remove it from the local index to avoid committing them.

Full code:

git pull origin master
git checkout commit_hash_right_before_files_were_deleted
git log --diff-filter D --pretty="oneline" --name-only --format= -l 0 commit_hash_right_before_files_were_deleted..commit_hash_where_files_were_deleted | sed '/^$/d' | zip deleted-files.zip -@
git checkout master
unzip deleted-files.zip
git reset -- `git diff --diff-filter=D --name-only commit_hash_where_files_were_deleted`

There are some additional arguments that we are passing to the git log command . We are passing the -l 0 argument to avoid git log from truncating the list of returned changed files. We are also passing the --format= argument to prevent git log from outputting the commit hash and the commit message; we only care about the list of changed files.

Tried a few solutions including trying to to the git update-index --assume-unchanged command but when I tried to pull from the remote branch, it would just keep deleting the files. This is best solution that met my needs.

Upvotes: 0

phd
phd

Reputation: 94397

There is no simple way to do that — git pull will delete the removed files anyway. You can restore deleted files from the previous commit(s). Providing the commit that removes the files is the last commit in the branch:

git pull
git checkout @~ -- `git diff --diff-filter=D --name-only @~`
git reset -- `git diff --diff-filter=D --name-only @~`

This restores deleted files from the commit before the last. git reset is required to remove the files from the index (cache): git checkout puts them there.

Upvotes: 2

Related Questions