AnErd
AnErd

Reputation: 425

How to keep only releases in git history

In my current repository I've got ~80 commits and 3 releases/tags (v0.1, v0.2, v0.3).

Is there a way to change the repository to only keep the three releases with all the changes between two subsequent releases in only a single commit. As a result I'd like to have v0.1 -> one commit -> v0.2 -> one commit -> v0.3.

For the future I found a way with branches, but I don't know to best change the git history.

Upvotes: 1

Views: 153

Answers (1)

AnoE
AnoE

Reputation: 8345

Yes, this is easily possible.

Without any fancy rewriting, rebasing, squashing, you can do it thus (assuming your existing local repository is in $REPOS1 and the path $REPOS2 does not exist yet:

git init $REPOS2

for $TAG in v0.1 v0.2 v0.3 v0.4 ; do
  cd $REPOS1
  git checkout $TAG
  rm -rf $REPOS2/*         # Assuming there are no files/dirs starting with "." except ".git", which we skip
  cp -r * $REPOS2/        
  cd $REPOS2
  git add -A ; git commit -m "$TAG" ; git tag "$TAG"
done

This might seem to be naive, but it actually works perfectly since git is only considering the content (and mode) of files when adding/committing, and it automagically detects if files between the two operations stay identical. It will re-use the existing objects and you will get a perfect "diff" at the end.

In the rm and cp steps, you want to a) delete everything from $REPOS2 except the $REPOS2/.git tree, and then copy everything from $REPOS1 to $REPOS2 except the $REPOS1/.git tree. If you do have other files/directories starting with a ., then you need to modify those commands as you see fit (maybe using find or tar --exclude or whatever you can think of).

If, at the end, you want to stay with this cleaned-up history, then throw away $REPOS1 and continue with $REPOS2. If, though, you want to keep your original history, then merge the two together:

cd $REPOS2
git remote add $REPOS1 repos1
git fetch repos1
for $TAG in master v0.1 v0.2 v0.3 v0.4 ; do
  git tag old-$TAG repos1/$TAG
done
git remote del repos1

(Assuming you never branched in $REPOS1.) After this, $REPOS2 also will contain all your old history, in tags starting with old-. You now can throw $REPOS1 away.

Upvotes: 1

Related Questions