git-merge-one-file.shon commit Sync with maint (259b5e6)
   1#!/bin/sh
   2#
   3# Copyright (c) Linus Torvalds, 2005
   4#
   5# This is the git per-file merge script, called with
   6#
   7#   $1 - original file SHA1 (or empty)
   8#   $2 - file in branch1 SHA1 (or empty)
   9#   $3 - file in branch2 SHA1 (or empty)
  10#   $4 - pathname in repository
  11#   $5 - original file mode (or empty)
  12#   $6 - file in branch1 mode (or empty)
  13#   $7 - file in branch2 mode (or empty)
  14#
  15# Handle some trivial cases.. The _really_ trivial cases have
  16# been handled already by git read-tree, but that one doesn't
  17# do any merges that might change the tree layout.
  18
  19USAGE='<orig blob> <our blob> <their blob> <path>'
  20USAGE="$USAGE <orig mode> <our mode> <their mode>"
  21LONG_USAGE="usage: git merge-one-file $USAGE
  22
  23Blob ids and modes should be empty for missing files."
  24
  25SUBDIRECTORY_OK=Yes
  26. git-sh-setup
  27cd_to_toplevel
  28require_work_tree
  29
  30if test $# != 7
  31then
  32        echo "$LONG_USAGE"
  33        exit 1
  34fi
  35
  36case "${1:-.}${2:-.}${3:-.}" in
  37#
  38# Deleted in both or deleted in one and unchanged in the other
  39#
  40"$1.." | "$1.$1" | "$1$1.")
  41        if { test -z "$6" && test "$5" != "$7"; } ||
  42           { test -z "$7" && test "$5" != "$6"; }
  43        then
  44                echo "ERROR: File $4 deleted on one branch but had its" >&2
  45                echo "ERROR: permissions changed on the other." >&2
  46                exit 1
  47        fi
  48
  49        if test -n "$2"
  50        then
  51                echo "Removing $4"
  52        else
  53                # read-tree checked that index matches HEAD already,
  54                # so we know we do not have this path tracked.
  55                # there may be an unrelated working tree file here,
  56                # which we should just leave unmolested.  Make sure
  57                # we do not have it in the index, though.
  58                exec git update-index --remove -- "$4"
  59        fi
  60        if test -f "$4"
  61        then
  62                rm -f -- "$4" &&
  63                rmdir -p "$(expr "z$4" : 'z\(.*\)/')" 2>/dev/null || :
  64        fi &&
  65                exec git update-index --remove -- "$4"
  66        ;;
  67
  68#
  69# Added in one.
  70#
  71".$2.")
  72        # the other side did not add and we added so there is nothing
  73        # to be done, except making the path merged.
  74        exec git update-index --add --cacheinfo "$6" "$2" "$4"
  75        ;;
  76"..$3")
  77        echo "Adding $4"
  78        if test -f "$4"
  79        then
  80                echo "ERROR: untracked $4 is overwritten by the merge." >&2
  81                exit 1
  82        fi
  83        git update-index --add --cacheinfo "$7" "$3" "$4" &&
  84                exec git checkout-index -u -f -- "$4"
  85        ;;
  86
  87#
  88# Added in both, identically (check for same permissions).
  89#
  90".$3$2")
  91        if test "$6" != "$7"
  92        then
  93                echo "ERROR: File $4 added identically in both branches," >&2
  94                echo "ERROR: but permissions conflict $6->$7." >&2
  95                exit 1
  96        fi
  97        echo "Adding $4"
  98        git update-index --add --cacheinfo "$6" "$2" "$4" &&
  99                exec git checkout-index -u -f -- "$4"
 100        ;;
 101
 102#
 103# Modified in both, but differently.
 104#
 105"$1$2$3" | ".$2$3")
 106
 107        case ",$6,$7," in
 108        *,120000,*)
 109                echo "ERROR: $4: Not merging symbolic link changes." >&2
 110                exit 1
 111                ;;
 112        *,160000,*)
 113                echo "ERROR: $4: Not merging conflicting submodule changes." >&2
 114                exit 1
 115                ;;
 116        esac
 117
 118        src1=$(git-unpack-file $2)
 119        src2=$(git-unpack-file $3)
 120        case "$1" in
 121        '')
 122                echo "Added $4 in both, but differently."
 123                orig=$(git-unpack-file $2)
 124                create_virtual_base "$orig" "$src2"
 125                ;;
 126        *)
 127                echo "Auto-merging $4"
 128                orig=$(git-unpack-file $1)
 129                ;;
 130        esac
 131
 132        git merge-file "$src1" "$orig" "$src2"
 133        ret=$?
 134        msg=
 135        if test $ret != 0 || test -z "$1"
 136        then
 137                msg='content conflict'
 138                ret=1
 139        fi
 140
 141        # Create the working tree file, using "our tree" version from the
 142        # index, and then store the result of the merge.
 143        git checkout-index -f --stage=2 -- "$4" && cat "$src1" >"$4" || exit 1
 144        rm -f -- "$orig" "$src1" "$src2"
 145
 146        if test "$6" != "$7"
 147        then
 148                if test -n "$msg"
 149                then
 150                        msg="$msg, "
 151                fi
 152                msg="${msg}permissions conflict: $5->$6,$7"
 153                ret=1
 154        fi
 155
 156        if test $ret != 0
 157        then
 158                echo "ERROR: $msg in $4" >&2
 159                exit 1
 160        fi
 161        exec git update-index -- "$4"
 162        ;;
 163
 164*)
 165        echo "ERROR: $4: Not handling case $1 -> $2 -> $3" >&2
 166        ;;
 167esac
 168exit 1