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