Git - 穷人合并永久忽略子分支

时间:2016-02-19 16:52:01

标签: git merge

给定两个分支,一个是另一个的子集 - 第一个中的文件更改在合并中的第二个中被永久忽略,其中开发者取消对文件的分级,然后提交剩余的合并。

AKA - 应该在子分支中的代码段由于合并不良而被忽略。这只是在大型开发环境中最近才出现的情况,其中子分支中的文件因重复使用此错误而丢失。 如何才能找到主分支中缺少更改的提交/文件?或者至少尝试解决问题(超过4个月的时间和数百次提交)。我们尝试过挑选我们可以找到的提交,但毫无疑问将无法找到它们。

有关如何在此处重现的详细信息

  
      
  1. 创建两个文件 - 在每个文件中写两行
  2.   
  3. 让他们掌握
  4.   
  5. 创建第二个分支
  6.   
  7. 切换到第二个分支 - 修改第二个文件中的文件行      
        
    1. 阶段和提交
    2.   
  8.   
  9. 切换到第一个分支 - 修改相同的文件行以进行冲突
  10.   
  11. 在第一个分支上 - 以前未修改过的文件,更改一行
  12.   
  13. 切换到第二个分支并合并第一个分支
  14.   
  15. 修复冲突和舞台文件 - >然后取消非冲突的文件
  16.   
  17. 提交第二个分支
  18.   
  19. 切换到第一个分支并放弃本地更改
  20.   
  21. 执行一些不影响第6步的新代码。
  22.   
  23. 阶段并提交新代码
  24.   
  25. 切换到第二个分支并合并第一个分支
  26.   

请注意,步骤10更改仍会显示,但步骤6仍然缺失。所有后续合并都将忽略步骤6中的更改,因为git认为他们的提交已合并(虽然在git的眼中是真的 - 但它对开发人员不起作用,因为合并错误且不应该提交)

1 个答案:

答案 0 :(得分:4)

不幸的是,对于没有git经验的人来说,这是常见的事情,因为他们看到他们没有在索引中修改的文件,因此丢弃它们。我编写了一个脚本来检测这些混乱的合并,并报告哪些文件是未分页的。它将ref spec作为参数(例如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中。这样,他们在临时区域看到的唯一文件是他们更改的文件,而不是其他人更改的文件。