2016-02-19 45 views
3

鑑於兩個分支,一個接一個的子集文件的更改 - 在第一文件更改第二永久忽略對合並其中開發UN-階段文件,然後承諾合併的其餘部分。混帳 - 合併差永久忽略子分支

AKA - 的代碼段,應在子分支,因爲合併差忽略。這只是最近在一個大型開發環境中發現的,在這個環境中,重複使用這個錯誤導致子分支中缺少文件。 如何找到缺少主分支更改的提交/文件?或者至少試圖解決這個問題(超過4個月的時間和數百次提交)。我們試圖挑選我們可以找到的承諾,但無疑將無法找到所有承諾。

細節上如何重現此

  1. 創建兩個文件 - 在每個文件寫兩行
  2. 提交他們掌握
  3. 創建第二支
  4. 切換到第二個分支 - 修改在第二文件文件線
    1. 階段和提交
  5. 切換到第一個分支 - 修改同一個文件行的第一個分支衝突
  6. - 在文件中並沒有修改之前,換行
  7. 切換到第二個分支和合並第一支
  8. 修復衝突和舞臺文件 - >然後unstage非衝突的文件
  9. 提交第二支
  10. 切換到第一分支和丟棄局部變化
  11. 做一些新的代碼不影響第6步。
  12. 階段和提交新的代碼
  13. 切換到第二分支和合並第一分支

注意,步驟而步驟6仍然缺少出現10次更改。因爲混帳相信他們的提交已合併所有後續的合併會忽略從第6步的變化(雖然真正的在混帳的眼睛 - 它不會爲開發工作,因爲合併是錯誤的,不應該被提交)

回答

4

不幸的是,這對於那些對git沒有經驗的人來說很常見,因爲他們看到的文件並沒有在索引中修改,因此放棄了它們。我已經編寫了一個腳本來檢測這些不合理的合併並報告哪些文件未分離。它需要一個參考規範作爲參數(例如masterHEAD^7..HEAD--since=2.weeks等),並且默認爲--all如果沒有參數被供給。它不是最有效的腳本(我真的需要改進計算兩個文件列表的差異的位)。我有一個更快的.exe版本,但我無法隨意分享,因爲我爲我的僱主寫了這個版本。無論如何,那就是:

isChangeInBaseChanges() { 
    for element in ${baseChanges[@]}; do 
    if [ $element == $change ] 
then 
return 1 
fi 
    done 
    return 0 
} 

revopts=`git rev-parse --revs-only $*` 

if ! [[ $revopts ]] 
then 
    revopts="--all" 
fi 

exitCode=0 

for merge in `git rev-list --min-parents=2 $revopts`; do 
    mergeChanges=`git log -m -1 --name-only --pretty="format:" $merge | sort -u` 
    mergeBase=`git merge-base $merge^ $merge^2` 
    baseChanges=`git diff --name-only $merge $mergeBase` 

    lostFiles=() 
    for change in ${mergeChanges[@]}; do 
    isChangeInBaseChanges 
if [ $? -ne 1 ] 
then 
    lostFiles+=($change) 
fi 
    done 

    if [ ${#lostFiles[@]} -ne 0 ] 
    then 
    exitCode=1 
    echo -n "Possible botched merge at " 
echo $merge 
echo "files with lost changes are: " 
for lostFile in ${lostFiles[@]}; do 
echo $lostFile 
done 
echo -------------------------------------------- 
    fi 

done 

exit $exitCode 

注意一兩件事可以做,以減少這種情況發生在未來(除了教育你的開發人員)是讓每個人都做好自己的特性分支工作,然後他們合併成master 。這樣,他們在他們的臨時區域看到的唯一文件是他們更改,而不是其他人更改。

+0

尼斯腳本。 +1。你用什麼語言做了那個exe?你在包裝git命令嗎? – VonC

+0

@VonC - 我用C#。不包裝git命令,我使用LibGit2Sharp。 –