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"$#"-eq7 31then 32echo"$LONG_USAGE" 33exit1 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.") 41if["$2"];then 42echo"Removing$4" 43else 44# read-tree checked that index matches HEAD already, 45# so we know we do not have this path tracked. 46# there may be an unrelated working tree file here, 47# which we should just leave unmolested. Make sure 48# we do not have it in the index, though. 49exec git update-index --remove --"$4" 50fi 51iftest -f"$4";then 52rm-f --"$4"&& 53rmdir-p"$(expr "z$4" : 'z\(.*\)/')"2>/dev/null || : 54fi&& 55exec git update-index --remove --"$4" 56;; 57 58# 59# Added in one. 60# 61".$2.") 62# the other side did not add and we added so there is nothing 63# to be done, except making the path merged. 64exec git update-index --add --cacheinfo"$6""$2""$4" 65;; 66"..$3") 67echo"Adding$4" 68iftest -f"$4" 69then 70echo"ERROR: untracked$4is overwritten by the merge." 71exit1 72fi 73 git update-index --add --cacheinfo"$7""$3""$4"&& 74exec git checkout-index -u -f --"$4" 75;; 76 77# 78# Added in both, identically (check for same permissions). 79# 80".$3$2") 81if["$6"!="$7"];then 82echo"ERROR: File$4added identically in both branches," 83echo"ERROR: but permissions conflict$6->$7." 84exit1 85fi 86echo"Adding$4" 87 git update-index --add --cacheinfo"$6""$2""$4"&& 88exec git checkout-index -u -f --"$4" 89;; 90 91# 92# Modified in both, but differently. 93# 94"$1$2$3"|".$2$3") 95 96case",$6,$7,"in 97*,120000,*) 98echo"ERROR:$4: Not merging symbolic link changes." 99exit1 100;; 101*,160000,*) 102echo"ERROR:$4: Not merging conflicting submodule changes." 103exit1 104;; 105esac 106 107 src2=`git-unpack-file$3` 108case"$1"in 109'') 110echo"Added$4in both, but differently." 111# This extracts OUR file in $orig, and uses git apply to 112# remove lines that are unique to ours. 113 orig=`git-unpack-file$2` 114 sz0=`wc -c <"$orig"` 115 @@DIFF@@ -u -La/$orig-Lb/$orig $orig $src2| git apply --no-add 116 sz1=`wc -c <"$orig"` 117 118# If we do not have enough common material, it is not 119# worth trying two-file merge using common subsections. 120expr$sz0 \<$sz1 \*2>/dev/null || : >$orig 121;; 122*) 123echo"Auto-merging$4" 124 orig=`git-unpack-file$1` 125;; 126esac 127 128# Be careful for funny filename such as "-L" in "$4", which 129# would confuse "merge" greatly. 130 src1=`git-unpack-file$2` 131 git merge-file"$src1""$orig""$src2" 132 ret=$? 133 msg= 134if[$ret-ne0];then 135 msg='content conflict' 136fi 137 138# Create the working tree file, using "our tree" version from the 139# index, and then store the result of the merge. 140 git checkout-index -f --stage=2--"$4"&&cat"$src1">"$4"||exit1 141rm-f --"$orig""$src1""$src2" 142 143if["$6"!="$7"];then 144if[-n"$msg"];then 145 msg="$msg, " 146fi 147 msg="${msg}permissions conflict:$5->$6,$7" 148 ret=1 149fi 150if["$1"=''];then 151 ret=1 152fi 153 154if[$ret-ne0];then 155echo"ERROR:$msgin$4" 156exit1 157fi 158exec git update-index --"$4" 159;; 160 161*) 162echo"ERROR:$4: Not handling case$1->$2->$3" 163;; 164esac 165exit1