Git – poor merge permanently ignores files changes in sub branches

Given two branches, one a subset of the other – a file change in the first is permanently ignored in the second on a merge where the developer un-stages the file and then commits the rest of the merge.

AKA – pieces of code that should be in sub branches are ignored because of poor merge. This is only coming to light recently in a large development environment where files are missing in the sub branch from repeated use of this mistake.
How can one go about finding the commits/files that are missing changes from the master branch? or at least attempt to fix the issue (over 4 months time and hundreds of commits). We have attempted cherry picking the commits that we can find but undoubtedly will be unable to find them all.

  • git maintaining 2 versions of the same project, with different users on each
  • Undo a fast-forward merge
  • How can I commit / remove a file starting by “:”?
  • SSLRead() return error -9806/15958)
  • Getting “fatal: This operation must be run in a work tree?” on bare repository
  • What are the conceptual differences between Merging, Stashing and Rebasing in Git?
  • Details on how to reproduce here

    1. create two files – write two lines in each file
    2. commit them to master
    3. create second branch
    4. switch to second branch – modify file line in second file
      1. stage and commit
    5. switch to first branch – modify same file line for conflict
    6. on first branch – on file that wasn’t modified before, change a line
    7. switch to second branch and merge first branch
    8. fix conflict and stage file -> then unstage non-conflicted file
    9. commit second branch
    10. switch to first branch and discard local changes
    11. do some new code that doesn’t affect step 6.
    12. stage and commit new code
    13. switch to second branch and merge first branch

    Notice that step 10 changes appears while step 6 is still missing. All subsequent merges will ignore the changes from step 6 since git believes their commits have been merged (although true in the eyes of git – it doesn’t work for the developer because the merge was wrong and shouldn’t have been committed)

  • Should I commit my `.idea/` folder?
  • Why does git rebase --onto not move any commits?
  • Atom text editor adds “^M” to empty lines
  • How can I use GIT-TFS and GIT-SVN in the same source tree?
  • Trying to install git on OSX: cannont exec 'git-credential-osxkeychain': Permission denied`
  • Make git pull (rebase) by default pull only from current downstream branch
  • One Solution collect form web for “Git – poor merge permanently ignores files changes in sub branches”

    This is, unfortunately, a common occurrence with people inexperienced with git, as they see files that they did not modify in the index, and thus discard them. I have written a script to detect these botched merges and report which files were unstaged. It takes a ref spec as an argument (e.g. master, HEAD^7..HEAD, --since=2.weeks, etc.) and defaults to --all if no argument is supplied. It is not the most efficient script (I really need to improve the bit that calculates the diff of two file lists); I have a faster .exe version, but am not at liberty to share it as I wrote it for my employer. Anyway, here it is:

     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
    

    Note that one thing you can do to reduce this happening in the future (besides educating your developers) is to have everyone do their work on feature branches, which they then merge into master. That way, the only files they see in their staging area are the ones they changed, not the ones changed by others.

    Git Baby is a git and github fan, let's start git clone.