diff --color-words: bit of clean-up
[git] / git-pull.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Junio C Hamano
4 #
5 # Fetch one or more remote refs and merge it/them into the current HEAD.
6
7 USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s strategy]... [<fetch-options>] <repo> <head>...'
8 LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEAD.'
9 SUBDIRECTORY_OK=Yes
10 OPTIONS_SPEC=
11 . git-sh-setup
12 set_reflog_action "pull $*"
13 require_work_tree
14 cd_to_toplevel
15
16 test -z "$(git ls-files -u)" ||
17         die "You are in the middle of a conflicted merge."
18
19 strategy_args= diffstat= no_commit= squash= no_ff= log_arg= verbosity=
20 curr_branch=$(git symbolic-ref -q HEAD)
21 curr_branch_short=$(echo "$curr_branch" | sed "s|refs/heads/||")
22 rebase=$(git config --bool branch.$curr_branch_short.rebase)
23 while :
24 do
25         case "$1" in
26         -q|--quiet)
27                 verbosity="$verbosity -q" ;;
28         -v|--verbose)
29                 verbosity="$verbosity -v" ;;
30         -n|--no-stat|--no-summary)
31                 diffstat=--no-stat ;;
32         --stat|--summary)
33                 diffstat=--stat ;;
34         --log|--no-log)
35                 log_arg=$1 ;;
36         --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
37                 no_commit=--no-commit ;;
38         --c|--co|--com|--comm|--commi|--commit)
39                 no_commit=--commit ;;
40         --sq|--squ|--squa|--squas|--squash)
41                 squash=--squash ;;
42         --no-sq|--no-squ|--no-squa|--no-squas|--no-squash)
43                 squash=--no-squash ;;
44         --ff)
45                 no_ff=--ff ;;
46         --no-ff)
47                 no_ff=--no-ff ;;
48         -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
49                 --strateg=*|--strategy=*|\
50         -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
51                 case "$#,$1" in
52                 *,*=*)
53                         strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
54                 1,*)
55                         usage ;;
56                 *)
57                         strategy="$2"
58                         shift ;;
59                 esac
60                 strategy_args="${strategy_args}-s $strategy "
61                 ;;
62         -r|--r|--re|--reb|--reba|--rebas|--rebase)
63                 rebase=true
64                 ;;
65         --no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase)
66                 rebase=false
67                 ;;
68         -h|--h|--he|--hel|--help)
69                 usage
70                 ;;
71         *)
72                 # Pass thru anything that may be meant for fetch.
73                 break
74                 ;;
75         esac
76         shift
77 done
78
79 error_on_no_merge_candidates () {
80         exec >&2
81         for opt
82         do
83                 case "$opt" in
84                 -t|--t|--ta|--tag|--tags)
85                         echo "Fetching tags only, you probably meant:"
86                         echo "  git fetch --tags"
87                         exit 1
88                 esac
89         done
90
91         curr_branch=${curr_branch#refs/heads/}
92         upstream=$(git config "branch.$curr_branch.merge")
93         remote=$(git config "branch.$curr_branch.remote")
94
95         if [ $# -gt 1 ]; then
96                 echo "There are no candidates for merging in the refs that you just fetched."
97                 echo "Generally this means that you provided a wildcard refspec which had no"
98                 echo "matches on the remote end."
99         elif [ $# -gt 0 ] && [ "$1" != "$remote" ]; then
100                 echo "You asked to pull from the remote '$1', but did not specify"
101                 echo "a branch to merge. Because this is not the default configured remote"
102                 echo "for your current branch, you must specify a branch on the command line."
103         elif [ -z "$curr_branch" ]; then
104                 echo "You are not currently on a branch, so I cannot use any"
105                 echo "'branch.<branchname>.merge' in your configuration file."
106                 echo "Please specify which branch you want to merge on the command"
107                 echo "line and try again (e.g. 'git pull <repository> <refspec>')."
108                 echo "See git-pull(1) for details."
109         elif [ -z "$upstream" ]; then
110                 echo "You asked me to pull without telling me which branch you"
111                 echo "want to merge with, and 'branch.${curr_branch}.merge' in"
112                 echo "your configuration file does not tell me either.  Please"
113                 echo "specify which branch you want to merge on the command line and"
114                 echo "try again (e.g. 'git pull <repository> <refspec>')."
115                 echo "See git-pull(1) for details."
116                 echo
117                 echo "If you often merge with the same branch, you may want to"
118                 echo "configure the following variables in your configuration"
119                 echo "file:"
120                 echo
121                 echo "    branch.${curr_branch}.remote = <nickname>"
122                 echo "    branch.${curr_branch}.merge = <remote-ref>"
123                 echo "    remote.<nickname>.url = <url>"
124                 echo "    remote.<nickname>.fetch = <refspec>"
125                 echo
126                 echo "See git-config(1) for details."
127         else
128                 echo "Your configuration specifies to merge the ref '${upstream#refs/heads/}' from the"
129                 echo "remote, but no such ref was fetched."
130         fi
131         exit 1
132 }
133
134 test true = "$rebase" && {
135         if ! git rev-parse -q --verify HEAD >/dev/null
136         then
137                 # On an unborn branch
138                 if test -f "$GIT_DIR/index"
139                 then
140                         die "updating an unborn branch with changes added to the index"
141                 fi
142         else
143                 git update-index --ignore-submodules --refresh &&
144                 git diff-files --ignore-submodules --quiet &&
145                 git diff-index --ignore-submodules --cached --quiet HEAD -- ||
146                 die "refusing to pull with rebase: your working tree is not up-to-date"
147         fi
148         oldremoteref= &&
149         . git-parse-remote &&
150         remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
151         oldremoteref="$(git rev-parse -q --verify "$remoteref")" &&
152         for reflog in $(git rev-list -g $remoteref 2>/dev/null)
153         do
154                 if test "$reflog" = "$(git merge-base $reflog $curr_branch)"
155                 then
156                         oldremoteref="$reflog"
157                         break
158                 fi
159         done
160 }
161 orig_head=$(git rev-parse -q --verify HEAD)
162 git fetch $verbosity --update-head-ok "$@" || exit 1
163
164 curr_head=$(git rev-parse -q --verify HEAD)
165 if test -n "$orig_head" && test "$curr_head" != "$orig_head"
166 then
167         # The fetch involved updating the current branch.
168
169         # The working tree and the index file is still based on the
170         # $orig_head commit, but we are merging into $curr_head.
171         # First update the working tree to match $curr_head.
172
173         echo >&2 "Warning: fetch updated the current branch head."
174         echo >&2 "Warning: fast forwarding your working tree from"
175         echo >&2 "Warning: commit $orig_head."
176         git update-index -q --refresh
177         git read-tree -u -m "$orig_head" "$curr_head" ||
178                 die 'Cannot fast-forward your working tree.
179 After making sure that you saved anything precious from
180 $ git diff '$orig_head'
181 output, run
182 $ git reset --hard
183 to recover.'
184
185 fi
186
187 merge_head=$(sed -e '/  not-for-merge   /d' \
188         -e 's/  .*//' "$GIT_DIR"/FETCH_HEAD | \
189         tr '\012' ' ')
190
191 case "$merge_head" in
192 '')
193         error_on_no_merge_candidates "$@"
194         ;;
195 ?*' '?*)
196         if test -z "$orig_head"
197         then
198                 die "Cannot merge multiple branches into empty head"
199         fi
200         if test true = "$rebase"
201         then
202                 die "Cannot rebase onto multiple branches"
203         fi
204         ;;
205 esac
206
207 if test -z "$orig_head"
208 then
209         git update-ref -m "initial pull" HEAD $merge_head "$curr_head" &&
210         git read-tree --reset -u HEAD || exit 1
211         exit
212 fi
213
214 merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
215 test true = "$rebase" &&
216         exec git-rebase $diffstat $strategy_args --onto $merge_head \
217         ${oldremoteref:-$merge_head}
218 exec git-merge $diffstat $no_commit $squash $no_ff $log_arg $strategy_args \
219         "$merge_name" HEAD $merge_head $verbosity