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 src1=$(git-unpack-file $2) 108 src2=$(git-unpack-file $3) 109case"$1"in 110'') 111echo"Added$4in both, but differently." 112 orig=$(git-unpack-file $2) 113 create_virtual_base "$orig""$src2" 114;; 115*) 116echo"Auto-merging$4" 117 orig=$(git-unpack-file $1) 118;; 119esac 120 121 git merge-file"$src1""$orig""$src2" 122 ret=$? 123 msg= 124if[$ret-ne0];then 125 msg='content conflict' 126fi 127 128# Create the working tree file, using "our tree" version from the 129# index, and then store the result of the merge. 130 git checkout-index -f --stage=2--"$4"&&cat"$src1">"$4"||exit1 131rm-f --"$orig""$src1""$src2" 132 133if["$6"!="$7"];then 134if[-n"$msg"];then 135 msg="$msg, " 136fi 137 msg="${msg}permissions conflict:$5->$6,$7" 138 ret=1 139fi 140if["$1"=''];then 141 ret=1 142fi 143 144if[$ret-ne0];then 145echo"ERROR:$msgin$4" 146exit1 147fi 148exec git update-index --"$4" 149;; 150 151*) 152echo"ERROR:$4: Not handling case$1->$2->$3" 153;; 154esac 155exit1