Skip tests that require a filesystem that obeys POSIX permissions
[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
93         echo "You asked me to pull without telling me which branch you"
94         echo "want to merge with, and 'branch.${curr_branch}.merge' in"
95         echo "your configuration file does not tell me either.  Please"
96         echo "name which branch you want to merge on the command line and"
97         echo "try again (e.g. 'git pull <repository> <refspec>')."
98         echo "See git-pull(1) for details on the refspec."
99         echo
100         echo "If you often merge with the same branch, you may want to"
101         echo "configure the following variables in your configuration"
102         echo "file:"
103         echo
104         echo "    branch.${curr_branch}.remote = <nickname>"
105         echo "    branch.${curr_branch}.merge = <remote-ref>"
106         echo "    remote.<nickname>.url = <url>"
107         echo "    remote.<nickname>.fetch = <refspec>"
108         echo
109         echo "See git-config(1) for details."
110         exit 1
111 }
112
113 test true = "$rebase" && {
114         git update-index --ignore-submodules --refresh &&
115         git diff-files --ignore-submodules --quiet &&
116         git diff-index --ignore-submodules --cached --quiet HEAD -- ||
117         die "refusing to pull with rebase: your working tree is not up-to-date"
118
119         . git-parse-remote &&
120         origin="$1"
121         test -z "$origin" && origin=$(get_default_remote)
122         reflist="$(get_remote_refs_for_fetch "$@" 2>/dev/null |
123                 sed "s|refs/heads/\(.*\):|\1|")" &&
124         oldremoteref="$(git rev-parse -q --verify \
125                 "refs/remotes/$origin/$reflist")"
126 }
127 orig_head=$(git rev-parse -q --verify HEAD)
128 git fetch $verbosity --update-head-ok "$@" || exit 1
129
130 curr_head=$(git rev-parse -q --verify HEAD)
131 if test -n "$orig_head" && test "$curr_head" != "$orig_head"
132 then
133         # The fetch involved updating the current branch.
134
135         # The working tree and the index file is still based on the
136         # $orig_head commit, but we are merging into $curr_head.
137         # First update the working tree to match $curr_head.
138
139         echo >&2 "Warning: fetch updated the current branch head."
140         echo >&2 "Warning: fast forwarding your working tree from"
141         echo >&2 "Warning: commit $orig_head."
142         git update-index --refresh 2>/dev/null
143         git read-tree -u -m "$orig_head" "$curr_head" ||
144                 die 'Cannot fast-forward your working tree.
145 After making sure that you saved anything precious from
146 $ git diff '$orig_head'
147 output, run
148 $ git reset --hard
149 to recover.'
150
151 fi
152
153 merge_head=$(sed -e '/  not-for-merge   /d' \
154         -e 's/  .*//' "$GIT_DIR"/FETCH_HEAD | \
155         tr '\012' ' ')
156
157 case "$merge_head" in
158 '')
159         case $? in
160         0) error_on_no_merge_candidates "$@";;
161         1) echo >&2 "You are not currently on a branch; you must explicitly"
162            echo >&2 "specify which branch you wish to merge:"
163            echo >&2 "  git pull <remote> <branch>"
164            exit 1;;
165         *) exit $?;;
166         esac
167         ;;
168 ?*' '?*)
169         if test -z "$orig_head"
170         then
171                 echo >&2 "Cannot merge multiple branches into empty head"
172                 exit 1
173         fi
174         if test true = "$rebase"
175         then
176                 echo >&2 "Cannot rebase onto multiple branches"
177                 exit 1
178         fi
179         ;;
180 esac
181
182 if test -z "$orig_head"
183 then
184         git update-ref -m "initial pull" HEAD $merge_head "$curr_head" &&
185         git read-tree --reset -u HEAD || exit 1
186         exit
187 fi
188
189 merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
190 test true = "$rebase" &&
191         exec git-rebase $diffstat $strategy_args --onto $merge_head \
192         ${oldremoteref:-$merge_head}
193 exec git-merge $diffstat $no_commit $squash $no_ff $log_arg $strategy_args \
194         "$merge_name" HEAD $merge_head $verbosity