mgilson mgilson - 2 years ago 94
Git Question

Rename variable in all commits on a given branch

My repo looks something like this:

(develop) D - E - F - G - H
(master) A - B - C

In the course of a code review (where I propose to merge
), I was asked to change the name of a variable that was introduced in
(e.g. change
) . If I were patient, I could look through all the commits in
, create fixup commits for each and then rebase away
entirely so that only
remains in the history.

It seems like there should be a better way. A little googling makes me believe that I should be able to make something work with
git filter-branch
, but as I'm re-writing history and all -- I'd prefer to be able to get it right the first time instead of doing a bunch of weird stuff and messing up my repo entirely...

A few helpful constraints for the purposes of this problem:

  • We can assume that the names
    are globally unique. e.g. if I did a
    sed -i 's/foo/bar/g' FILE
    , I'll be left with the result I want without worrying about names like
    being incorrectly translated to

  • I'm using OS-X -- So POSIX compliant invocations of shell utilities are preferred (though I can work to translate from GNU variants if I must)

Answer Source

You were already quite close with your attempt.

git filter-branch --tree-filter 'sed -i "s/foo/bar/g" $FILES'  D^..H HEAD

assuming you are on your develop branch and you replace D and H with the commit index.

If you mess something up, there is always the reflog. You can also branch before or hand-write the commit reference before as a safeguard. I would recommend performing this in a separate branch, however.

$FILES here is a list of files containing your variable. I guess you could replace it with $(git grep --name-only foo). I didn't try it wowever, and you might have to escape the $ symbol. The simplest option is to hand-write a list of files there, of course.

Edit: just tried. it works without escaping. sed however fails if there is no input file, aborting the process. You also get a copy of your old refs in .git/refs/original/, so you might need to add -f after git filter-branch if this is not your first attempt, in order to overwrite the copy.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download