delete file history with bazaar

2019-03-28 12:09发布

问题:

Someone committed all binaries to our bazaar trunk, and I want to get rid of it. `bzr del file' only deletes the file from the current revision, but not the history of the file.

Is there a way we can remove the file history so that we don't all have to download hundreds of MBs of data?

回答1:

There is 2 ways. But you need to be ready that you will re-create the part (or even full) of your branch history, so your current (local) branches will become incompatible with new branch after deleting the file.

1) Manual way. You can create a copy of your branch to revision just before big files have added. Then you need semi-manually re-commit your further revisions and exclude big files. Use replay command from bzr-rewrite plugin (former bzr-rebase) to replay those revisions where no changes to big files present. And use merge -cN for revisions where changes to big files are present, manually delete these files and commit. Thus you will keep most of your history intact and will keep unique file ids for other files of your branch.

2) Use bzr-fastimport plugin to export your history as fast-import stream with bzr fast-export command. Then filter out big files with bzr fast-import-filter -x FILE command. And in the end re-create new branch without big files with bzr fast-import command. This method w3ill destroy all your history and all your files will get new file ids, so your new branch will be totally incompatible with old branch.

In any case, if you have shared repository with big files history inside you need to create new empty shared repository and put your new filtered branch there.



回答2:

If the binary files were added in the last commit, you can uncommit it.

bzr uncommit

This will leave your working tree in the state it was just before you wrote "bzr commit". Then delete the files and re-commit.

Check the bazaar doc on undoing mistakes for more detail.

You can use the -r option to undo several commits in one operation: bzr uncommit -r -4

Other option, if you do not care of the revision history:
You can do an export of your branch (bzr export DESTINATION) and then create a new trunk.
The export command will simply export the head repository, without any history.



回答3:

I was looking for a way to get rid of CVS/ dirs that made it's way into all my bzr commits. I'm new to bzr, so at the time, I wasn't yet sure how I was going to handle them. (At work the central repo is CVS, but I use bzr locally to help me). Here is an example of what I did to get rid of some CVS dirs in my project, it's not meant to be perfect, but a quick hack :)

You have a project called 'projAAA' in dir /home/user/dev

Export the current bzr project (for bzr import)

cd /home/user/dev  
bzr fast-export --no-plain projAAA export.gz

Move that export to an empty dir (the filter for some reason looks at other dirs where it's run)

cp export.gz ~/tmp/rewrite/  
cd ~/tmp/rewrite

Script_1

This script takes the export and filters everything you supply with -x
Unfortunately -x doesnt seem to work with wildcards, so you have to give exact values/paths/files
It runs in ~/tmp/rewrite

#!/bin/bash  
rm -r new.import/ out.filtered  
bzr fast-import-filter -x gradle/wrapper/CVS -x gradle/CVS -x .cvsignore* -x .cvsignore -x ChangeFile -x src/main/groovy/cvs/util/CVS -x src/main/groovy/cvs/CVS -x src/main/groovy/CVS -x src/main/java/cvs/util/CVS -x src/main/java/cvs/CVS -x src/main/java/CVS -x src/main/resources/CVS -x src/main/CVS -x src/test/groovy/cvs/util/CVS -x src/test/groovy/cvs/CVS -x src/test/groovy/CVS -x src/test/resources/CVS -x src/test/CVS -x src/CVS -x CVS export.gz > out.filtered  
bzr fast-import out.filtered new.import

Now the dir "new.import" will contain everything but what you've filtered out.
Run the following script to look through the entire revision history of that new import for stuff that might still be there, that you dont want, for which you should add another -x value in Script_1 (which I will then rerun until Im happy)

Script_2:

Run this in ~/tmp/rewrite:

#!/bin/bash  

THISDIR=$(pwd)
pushd new.import/trunk/

#clean file
echo `date` > $THISDIR/search.out

# I manually enter the revisions that exist here, if you only have 1 to 19, change this accordingly:
for i in `seq 1 70`;
do
  echo $i
  printf "\n============== rev $i =================\n" >> $THISDIR/search.out
  bzr revert -r$i
  # Change this find to look for things you want to filter out
  find . -name CVS -type d >> $THISDIR/search.out 2>&1
done

popd

If you now look inside search.out, you could see what the search has found, and then add those to the previous script until you're happy.

So, in essence, I re-do this a couple of times until I'm happy;

  • Run Script_1 to export, filter, rewrite a branch.
  • Then Script_2 to search the new branch to be sure it's all gone, if not, add more -x entries
  • Re-run ammended Script_1.
  • Repeat