2017-09-14 87 views
7

我使用這個腳本修改提交:混帳:更改提交者信息

rm -rf repo 

echo "clonning $1" 
git clone $1 repo 

cd repo 
git checkout dev 

echo "setting remote origin to $2" 
git remote set-url origin $2 

array=('[email protected]il.com' '[email protected]') 
for OLD_EMAIL in "${array[@]}" 
do 
    echo $OLD_EMAIL 
    git filter-branch -f --env-filter ' 
    CORRECT_NAME="New name" 
    CORRECT_EMAIL="[email protected]" 
    if [ "$GIT_COMMITTER_EMAIL" = '$OLD_EMAIL' ] 
    then 
     export GIT_COMMITTER_NAME="$CORRECT_NAME" 
     export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL" 
    fi 
    if [ "$GIT_AUTHOR_EMAIL" = '$OLD_EMAIL' ] 
    then 
     export GIT_AUTHOR_NAME="$CORRECT_NAME" 
     export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL" 
    fi 
    ' --tag-name-filter cat -- --tags 
done 
echo "Authors list:" 
git log --format='%cE' | sort -u 
echo -n "Push to destination (y/n)? " 
read answer 
if echo "$answer" | grep -iq "^y" ;then 
    git push 
else 
    echo Aborted 
fi 

cd ../ 

它從第一回購提取數據,修改提交者信息,並推到第二回購。

如果有人直接提交第二個回購,則會出現問題。我如何將這些更改應用到第一個回購?

+0

只是好奇:所以你想在這兩個回購協議的所有變化?爲什麼你不能只使用一個回購?僅僅關於提交者信息? –

+0

是的,首先回購應該包含原始提交,以及第二次修改的提交。 – stkvtflw

+0

所以也許人們不應該直接提交到第二個存儲庫?由於您的存儲庫不共享歷史記錄(因爲所有已修改的提交),因此將更改從一個合併到另一個將會很麻煩。 – larsks

回答

0

你已經兩個選項來完成這件事:

  1. 如果您信任的用戶,你可以讓他們改變他們的電子郵件(或者只有這個混帳回購協議或全部回購,加上--global所有回購)
git config user.email [email protected] 
  • 如果要通過一個預提交的git鉤執行它,將要添加到S第二個存儲庫,並讓他們都拉動新的更新。 更多關於此可以發現herehere
  • 6

    如果我正確理解你的問題(閱讀後的評論),您的回購目前看起來是這樣的:

    Initial State

    第一回購(廣告)的提交已修改創建另一個提交(a'-d'),這些提交被推入第二個回購,然後增加了額外的提交(例如)。

    重新編輯你的歷史

    因爲你沒有1:在兩個回購的身份信息與1的關係,試圖修改A'd」與過濾分支,以恢復原來的歷史,而理論上可能的,將需要一種方法,將積極地確定'原始提交',沒有積極確定一個提交(其散列)所需的一條信息。

    一個COMMIT基本上是由信息幾塊組成:

    1. 提交的父(S)
    2. 作者的身份信息的樹
    3. 哈希(一個或多個)的哈希
    4. 創作
    5. 的提交者的身份信息
    6. 的時間戳的時間戳提交
    7. 的提交信息
    8. 的這一切都被散列以創建您提交的唯一標識所有的信息

    大小。修改了2,3,5和8後,我們留下的樹不一定是唯一的,時間戳(不一定是唯一的)和提交消息(不一定是唯一的)。

    奇怪的是,你可以得到只是比較樹和時間戳一個像樣的比賽,讓我們寫這情景有點僞代碼。

    # create a variable to hold the information from teh current commit 
    pseudoidentifier=$TREE + $AUTHOR_TIMESTAMP 
    
    # go to the first repo 
    cd /path/to/firstrepo 
    
    # output the log | grep to search | sed to remove everything after delimeter 
    oldhash=`git log --format="{hash}~{tree}{authortimestamp}" | grep pseudoidenfier | sed "s/~.+$//"` 
    
    # get the new identity using a custom formatted show command 
    newidentity=`git show -q --format="{formatted identity}" $oldhash` 
    
    # parse out the name and email, probably with sed 
    CORRECT_NAME=`sed 's/pattern//' $newidentity` 
    CORRECT_EMAIL=`sed 's/pattern//' $newidentity` 
    
    # go to the second repo 
    cd /path/to/secondrepo 
    
    export GIT_COMMITTER_NAME="$CORRECT_NAME" 
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL" 
    

    不幸的是,這將是緩慢的編寫和困難且耗時的測試。可能需要多次重新運行整個事情。由於您的最終目標是重新統一代碼。還有其他幾個選項可能會導致更少的頭痛並且速度更快。特別是如果你確實需要保持第二個回購與完整的身份更新。

    替代方法

    如果沒有共同的歷史,你可以使用稍微更手動方式仍然會帶來兩成同步。以下是我在這種情況下推薦的三種方法。

    一點前期工作

    在我們開始之前,我們可以檢查,看看是否在碼d和d」確實是相同的。我們可以通過使用git的show命令做到這一點:

    $ git show -q --format="%T" d 
    a017285da45ec06fc744815f33a2e22627f4a799 
    $ git show -q --format="%T" d' 
    a017285da45ec06fc744815f33a2e22627f4a799 
    

    該命令將輸出的樹對象提交點,如果兩棵樹匹配,你在處理相同的代碼。完全可能在沒有匹配的代碼庫的情況下執行以下過程,但在這種情況下您可能需要解決衝突。這一步實際上只是告訴你兩個人會如何輕鬆地聚在一起。

    的摘櫻桃方法

    如果您最初用來修改提交回購是完整的,你可以從兩個分支取到一個單一的回購並嘗試使用摘櫻桃複製的提交。

    git checkout <branch at d> 
    git cherry-pick d'...g 
    

    (注意,語法是3點)從後(但不包括)d」至多幷包括克到d每次提交這將應用更改。創建新的提交e'-g'。

    History after cherry-pick

    的修補方法

    如果你沒有一個簡單的方法來把從兩個分支的變化成一個單一的回購,你可以創建在第二的提交了一系列補丁回購並將其應用到第一個。

    在第二回購

    git checkout <branch of g> 
    git format-patch --output-directory <dir> d'...g 
    

    (同樣,語法是3點)這會輸出用於每個一系列補丁文件之後(並且不包括)d」至多幷包括克提交。然後將這些文件複製到可以從第一個回購庫獲得的位置以應用該修補程序。

    在第回購

    git checkout <branch of d> 
    git am /path/to/patches/* 
    

    你會在你從櫻桃挑選方法也做了同樣的位置結束。

    History after patch

    創建移植

    如果有很多的衝突,你不需要保留身份改變的信息,你也可以使用git replace,進行接枝。

    git replace --graft e d 
    

    這將創建犯電子商務與d副本作爲家長,並添加說,使用電子參考」提交時,它試圖訪問電子。有效地制定雙方的共同祖先並允許您執行傳統合並(h)。

    enter image description here

    然後呢?

    保持兩個沒有共同歷史同步的回購會一直導致您這樣的問題,並且隨着兩者緩慢發生分歧(例如,在您解決衝突時),它們會變得更糟。隨着時間的推移,這兩種方法都需要越來越多的資源來維持這兩種回購。

    我會建議,一旦兩個回購同步,選擇其中之一,並從那時起專門使用。如果您需要兩個遙控器,只需將該回購推送到他們兩個。然後,您可以輕鬆使用任何經過驗證的真實工作流程來維護兩個回購。

    如果這不是一個選項,我建議您仔細檢查兩個回購站頭部的樹木,以確認它們經常是一點一點地相同。

    +0

    >試圖修改a'-d以重新統一歷史記錄將不起作用,它只會創建與原始提交相同作者的第二組重複提交,但它們不會是相同的提交 <=這不是真的 - 只是嘗試玩一個提交,來回更改名稱或電子郵件 - 你會看到,放回完全相同的名稱和完全相同的電子郵件恢復主機 – stkvtflw

    +0

    @stkvtflw呵呵...我立場糾正。我現在將刪除不正確的聲明,並在幾個小時內擴大我的答案 – LightBender