Running filter-branch over a range of commits

前端 未结 8 1298
夕颜
夕颜 2020-12-02 14:26
git filter-branch --env-filter \'
export GIT_AUTHOR_EMAIL=\"foo@example.com\"
export GIT_AUTHOR_NAME=\"foo\"\' -- commita..commitb

Results in

相关标签:
8条回答
  • 2020-12-02 14:46

    Enclose you filter commands in an if-statement that checks for that range. You can check whether a commit is within a given range with this command:

    git rev-list start..end | grep **fullsha**
    

    The current commit will be stored in $GIT_COMMIT in your filter. So your filter becomes:

    git filter-branch --env-filter '
      if git rev-list commita..commitb | grep $GIT_COMMIT; then
        export GIT_AUTHOR_EMAIL="foo@example.com"
        export GIT_AUTHOR_NAME="foo"
      fi' -- ^commita --all
    

    If you want to only rewrite your current branch, replace --all with HEAD

    0 讨论(0)
  • 2020-12-02 14:47

    Use filter-branch's --setup parm and some shell power:

    git filter-branch --setup '
    for id in `git rev-list commitA..commitB`; do
             eval filterfor_$id=rewrite
    done
    rewrite() {
            GIT_AUTHOR_NAME="Frederick. O. Oosball"
            GIT_AUTHOR_EMAIL=foobar@example.org
    }
    ' --env-filter 'eval \$filterfor_$GIT_COMMIT'
    
    0 讨论(0)
  • 2020-12-02 14:50

    You cannot apply the filter-branch in the middle of the history, as said by @kan. You must apply from your known commit to the end of the history

    git filter-branch --env-filter '...' SHA1..HEAD
    

    Filter-branch can check for the commit author or other information, to chose to change or not the commit, so there are ways to accomplish what you want, see https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History, look for "Changing Email Addresses Globally"

    Remember: if you have pushed the commits to a public repository you should not user filter-branch

    0 讨论(0)
  • 2020-12-02 14:52

    The solution from @Acron seems wrong to me. I would suggest following to change between refa and refb including both hashes:

    1. git tag master.bak
    2. git reset --hard refa
    3. git filter-branch --env-filter ' export GIT_AUTHOR_EMAIL="foo@example.com"' refa^..master
    4. git cherry-pick refb..master.bak
    5. git tag -d master.bak
    0 讨论(0)
  • 2020-12-02 14:55

    The cleanest solution I found was to do the following:

    1. Create a temporary branch at refb.
    2. Apply the branch filter on refa..temp.
    3. Rebase onto the temporary branch and delete it.

    ie.

    git branch temp refb
    
    git filter-branch --env-filter '
    export GIT_AUTHOR_EMAIL="foo@example.com"' refa..temp
    
    git rebase temp
    git branch --delete temp
    
    0 讨论(0)
  • 2020-12-02 14:56

    I do it this way.

    Let's say you want to filter the content of a branch called branch-you-are-filtering.

    Assume that there's an ancestor commit to that branch, with a ref called ref-for-commit-to-stop-at.

    git filter-branch --commit-filter 'YOUR_FILTER_COMMANDS' branch-you-are-filtering...ref-for-commit-to-stop-at
    

    After executing, the commit at ref-for-commit-to-stop-at will not be altered. All the filtered\changed commits in branch branch-you-are-filtering will be based on ref-for-commit-to-stop-at.

    Whether or not you're using --commit-filter or something else is up to you.

    0 讨论(0)
提交回复
热议问题