filter-branch: use --simplify-merges
[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= no_stat= no_commit= squash= no_ff= log_arg=
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         -n|--no-stat|--no-summary)
27                 no_stat=-n ;;
28         --stat|--summary)
29                 no_stat=$1 ;;
30         --log|--no-log)
31                 log_arg=$1 ;;
32         --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
33                 no_commit=--no-commit ;;
34         --c|--co|--com|--comm|--commi|--commit)
35                 no_commit=--commit ;;
36         --sq|--squ|--squa|--squas|--squash)
37                 squash=--squash ;;
38         --no-sq|--no-squ|--no-squa|--no-squas|--no-squash)
39                 squash=--no-squash ;;
40         --ff)
41                 no_ff=--ff ;;
42         --no-ff)
43                 no_ff=--no-ff ;;
44         -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
45                 --strateg=*|--strategy=*|\
46         -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
47                 case "$#,$1" in
48                 *,*=*)
49                         strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
50                 1,*)
51                         usage ;;
52                 *)
53                         strategy="$2"
54                         shift ;;
55                 esac
56                 strategy_args="${strategy_args}-s $strategy "
57                 ;;
58         -r|--r|--re|--reb|--reba|--rebas|--rebase)
59                 rebase=true
60                 ;;
61         --no-r|--no-re|--no-reb|--no-reba|--no-rebas|--no-rebase)
62                 rebase=false
63                 ;;
64         -h|--h|--he|--hel|--help)
65                 usage
66                 ;;
67         *)
68                 # Pass thru anything that may be meant for fetch.
69                 break
70                 ;;
71         esac
72         shift
73 done
74
75 error_on_no_merge_candidates () {
76         exec >&2
77         for opt
78         do
79                 case "$opt" in
80                 -t|--t|--ta|--tag|--tags)
81                         echo "Fetching tags only, you probably meant:"
82                         echo "  git fetch --tags"
83                         exit 1
84                 esac
85         done
86
87         curr_branch=${curr_branch#refs/heads/}
88
89         echo "You asked me to pull without telling me which branch you"
90         echo "want to merge with, and 'branch.${curr_branch}.merge' in"
91         echo "your configuration file does not tell me either.  Please"
92         echo "name which branch you want to merge on the command line and"
93         echo "try again (e.g. 'git pull <repository> <refspec>')."
94         echo "See git-pull(1) for details on the refspec."
95         echo
96         echo "If you often merge with the same branch, you may want to"
97         echo "configure the following variables in your configuration"
98         echo "file:"
99         echo
100         echo "    branch.${curr_branch}.remote = <nickname>"
101         echo "    branch.${curr_branch}.merge = <remote-ref>"
102         echo "    remote.<nickname>.url = <url>"
103         echo "    remote.<nickname>.fetch = <refspec>"
104         echo
105         echo "See git-config(1) for details."
106         exit 1
107 }
108
109 test true = "$rebase" && {
110         git update-index --ignore-submodules --refresh &&
111         git diff-files --ignore-submodules --quiet &&
112         git diff-index --ignore-submodules --cached --quiet HEAD -- ||
113         die "refusing to pull with rebase: your working tree is not up-to-date"
114
115         . git-parse-remote &&
116         origin="$1"
117         test -z "$origin" && origin=$(get_default_remote)
118         reflist="$(get_remote_refs_for_fetch "$@" 2>/dev/null |
119                 sed "s|refs/heads/\(.*\):|\1|")" &&
120         oldremoteref="$(git rev-parse --verify \
121                 "refs/remotes/$origin/$reflist" 2>/dev/null)"
122 }
123 orig_head=$(git rev-parse --verify HEAD 2>/dev/null)
124 git fetch --update-head-ok "$@" || exit 1
125
126 curr_head=$(git rev-parse --verify HEAD 2>/dev/null)
127 if test "$curr_head" != "$orig_head"
128 then
129         # The fetch involved updating the current branch.
130
131         # The working tree and the index file is still based on the
132         # $orig_head commit, but we are merging into $curr_head.
133         # First update the working tree to match $curr_head.
134
135         echo >&2 "Warning: fetch updated the current branch head."
136         echo >&2 "Warning: fast forwarding your working tree from"
137         echo >&2 "Warning: commit $orig_head."
138         git update-index --refresh 2>/dev/null
139         git read-tree -u -m "$orig_head" "$curr_head" ||
140                 die 'Cannot fast-forward your working tree.
141 After making sure that you saved anything precious from
142 $ git diff '$orig_head'
143 output, run
144 $ git reset --hard
145 to recover.'
146
147 fi
148
149 merge_head=$(sed -e '/  not-for-merge   /d' \
150         -e 's/  .*//' "$GIT_DIR"/FETCH_HEAD | \
151         tr '\012' ' ')
152
153 case "$merge_head" in
154 '')
155         case $? in
156         0) error_on_no_merge_candidates "$@";;
157         1) echo >&2 "You are not currently on a branch; you must explicitly"
158            echo >&2 "specify which branch you wish to merge:"
159            echo >&2 "  git pull <remote> <branch>"
160            exit 1;;
161         *) exit $?;;
162         esac
163         ;;
164 ?*' '?*)
165         if test -z "$orig_head"
166         then
167                 echo >&2 "Cannot merge multiple branches into empty head"
168                 exit 1
169         fi
170         ;;
171 esac
172
173 if test -z "$orig_head"
174 then
175         git update-ref -m "initial pull" HEAD $merge_head "" &&
176         git read-tree --reset -u HEAD || exit 1
177         exit
178 fi
179
180 merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit
181 test true = "$rebase" &&
182         exec git-rebase $strategy_args --onto $merge_head \
183         ${oldremoteref:-$merge_head}
184 exec git-merge $no_stat $no_commit $squash $no_ff $log_arg $strategy_args \
185         "$merge_name" HEAD $merge_head