Skip to content

Commit 126d33f

Browse files
author
Tomas Lundell
committed
Add --abort and --continue options, fix bugs
1 parent 601d253 commit 126d33f

File tree

2 files changed

+101
-63
lines changed

2 files changed

+101
-63
lines changed

git-lib.rb

Lines changed: 77 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/local/bin/ruby
22
require 'optparse'
3+
require 'fileutils'
34

45
def getconfig(conf)
56
output=`git config --get #{conf}`.strip
@@ -69,6 +70,14 @@ def run(cmd)
6970
options[:password] = val
7071
end
7172

73+
opts.on("--abort", "Used to abort a lib pull.") do
74+
options[:abort] = true
75+
end
76+
77+
opts.on("--continue", "Used to continue after resolving merge conflicts during a lib pull.") do
78+
options[:continue] = true
79+
end
80+
7281
opts.on_tail("-h", "--help", "Show this message.") do
7382
puts opts
7483
exit
@@ -102,6 +111,23 @@ def ensure_clean()
102111
abort "Index has modifications. Cannot pull." unless $?.success?
103112
end
104113

114+
def produce_merge_commit(head_rev, fetch_rev, commit_message)
115+
if !head_rev.empty? && head_rev != fetch_rev then
116+
headp = "-p #{head_rev}"
117+
else
118+
headp = ""
119+
end
120+
121+
tree = %x(git write-tree).strip
122+
abort "git write-tree failed" unless $?.success?
123+
124+
commit = %x(git commit-tree #{tree} #{headp} -p #{fetch_rev} -m '#{commit_message}')
125+
abort "git commit failed" unless $?.success?
126+
127+
%x(git reset #{commit})
128+
abort "git reset failed" unless $?.success?
129+
end
130+
105131
commands = {
106132

107133
"split" => lambda do
@@ -132,76 +158,85 @@ def ensure_clean()
132158
end,
133159

134160
"pull" => lambda do
135-
ensure_clean()
161+
git_dir = %x(git rev-parse --git-dir).strip
162+
lib_pull_file = "#{git_dir}/LIB_PULL"
136163

137-
puts "Fetching remote lib..."
138-
%x(git fetch #{options[:url]} #{options[:refspec]})
139-
abort "Could not fetch from repository: #{options[:url]}" unless $?.success?
164+
if (options[:abort] || options[:continue])
165+
abort "Not currently in a lib pull" unless File.exists? lib_pull_file
166+
head_rev, fetch_rev, libname = File.read(lib_pull_file).split(' ')
140167

141-
fetch_rev = %x(git rev-parse --revs-only fetch_head).split(' ')[0].strip
142-
head_rev = %x(git rev-parse head).strip
143-
if !head_rev.empty? && head_rev != fetch_rev then
144-
headp = "-p #{head_rev}"
168+
if (options[:abort])
169+
%x(git reset --hard #{head_rev})
170+
elsif (options[:continue])
171+
commit_message = "Merged lib \"#{libname}\""
172+
end
145173
else
146-
headp = ""
147-
end
174+
ensure_clean()
175+
libname = options[:libname]
148176

149-
if !Dir.exists? options[:prefix]
150-
puts "Adding lib..."
177+
puts "Fetching remote lib..."
178+
%x(git fetch #{options[:url]} #{options[:refspec]})
179+
abort "Could not fetch from repository: #{options[:url]}" unless $?.success?
151180

152-
%x(git read-tree --prefix="#{options[:prefix]}" fetch_head)
153-
abort "git read-tree failed" unless $?.success?
181+
fetch_rev = %x(git rev-parse --revs-only fetch_head).split(' ')[0].strip
182+
head_rev = %x(git rev-parse head).strip
183+
File.write(lib_pull_file, "#{head_rev} #{fetch_rev}")
154184

155-
%x(git checkout -- "#{options[:prefix]}")
156-
abort "git checkout tree failed" unless $?.success?
185+
if !Dir.exists? options[:prefix]
186+
puts "Adding lib..."
157187

158-
commit_message = "Add lib \"#{options[:libname]}\""
159-
else
160-
puts "Rejoining lib..."
161-
split_sha, success = call "#{gitsubtree} --prefix #{options[:prefix]} --with fetch_head"
162-
abort "Split failed" unless success
188+
%x(git read-tree --prefix="#{options[:prefix]}" fetch_head)
189+
abort "git read-tree failed" unless $?.success?
163190

164-
puts "Merging lib..."
191+
%x(git checkout -- "#{options[:prefix]}")
192+
abort "git checkout tree failed" unless $?.success?
165193

166-
if !%x(git rev-list #{split_sha}..fetch_head).empty?
167-
%x(git merge -s ours -m 'Rejoin lib "#{options[:libname]}"' #{split_sha})
168-
169-
commit_message = "Merged lib \"#{options[:libname]}\""
170-
output = %x(git merge -Xsubtree=#{options[:prefix]} --message='#{commit_message}' -q --no-commit fetch_head 2>&1)
171-
abort "Merge failed:\n#{output}" unless $?.success?
194+
commit_message = "Add lib \"#{libname}\""
172195
else
173-
puts "Everything up-to-date"
196+
puts "Rejoining lib..."
197+
split_sha, success = call "#{gitsubtree} --prefix #{options[:prefix]} --with fetch_head"
198+
abort "Split failed" unless success
199+
200+
puts "Merging lib..."
201+
202+
if !%x(git rev-list #{split_sha}..fetch_head).empty?
203+
%x(git merge -s ours -m 'Rejoin lib "#{options[:libname]}"' #{split_sha})
204+
205+
commit_message = "Merged lib \"#{libname}\""
206+
output = %x(git merge -Xsubtree=#{options[:prefix]} --message='#{commit_message}' -q --no-commit fetch_head 2>&1)
207+
abort 'Merge failed; Fix conflicts and then issue "git lib pull --continue"' unless $?.success?
208+
else
209+
puts "Everything up-to-date"
210+
end
174211
end
175212
end
176213

177214
if commit_message
178-
tree = %x(git write-tree).strip
179-
abort "git write-tree failed" unless $?.success?
180-
181-
commit = %x(git commit-tree #{tree} #{headp} -p #{fetch_rev} -m '#{commit_message}')
182-
abort "git commit failed" unless $?.success?
183-
184-
%x(git reset #{commit})
215+
produce_merge_commit(head_rev, fetch_rev, commit_message)
185216
end
217+
218+
FileUtils.rm(lib_pull_file)
186219
end,
187220
}
188221

189222

190223
########################################
191224
# Main
192225

193-
if ARGV.length != 2 then
226+
if ARGV.length < 1 then
194227
puts option_parser
195228
else
196229
commandname = ARGV[0]
197230
options[:libname] = ARGV[1]
198231

199-
options[:url] = %x(#{githost} url-for #{options[:libname]} #{host_options(options)}).strip
200-
exit(1) unless $?.success?
232+
if !(options[:abort] || options[:continue])
233+
options[:url] = %x(#{githost} url-for #{options[:libname]} #{host_options(options)}).strip
234+
exit(1) unless $?.success?
201235

202-
if not options[:prefix] then
203-
reldir = pwd[gitdir.length + 1..-1] || '.'
204-
options[:prefix] = reldir != '.' && File.join(reldir, options[:libname]) || options[:libname]
236+
if not options[:prefix] then
237+
reldir = pwd[gitdir.length + 1..-1] || '.'
238+
options[:prefix] = reldir != '.' && File.join(reldir, options[:libname]) || options[:libname]
239+
end
205240
end
206241

207242
command = commands[commandname]

git-split-lib.sh

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ cache_setup()
9292
mkdir -p "$cachedir" || die "Can't create new cachedir: $cachedir"
9393
debug "Using cachedir: $cachedir" >&2
9494
fi
95+
rm -f "$cachedir/latest_new"
96+
rm -f "$cachedir/latest_old"
9597
}
9698

9799
cache_get()
@@ -218,38 +220,39 @@ cmd_split()
218220

219221
# Optimisation: Only look at objects past merge base
220222
merge_base="$(git merge-base $revs $with)"
221-
if [ $? == 0 ]; then
223+
if [ -n "$merge_base" ]; then
222224
grl='git rev-list --topo-order --reverse --parents --ancestry-path $merge_base..$revs'
223225
fi
224226
fi
225227

226228
eval "$grl" |
227229
while read rev parents; do
228230
debug "Processing commit: $rev"
229-
exists=$(cache_get $rev)
230-
if [ -n "$exists" ]; then
231-
debug " prior: $exists"
232-
continue
233-
fi
234-
debug " parents: $parents"
235-
newparents=$(cache_get $parents)
236-
debug " newparents: $newparents"
237-
238-
tree=$(subtree_for_commit $rev "$dir")
239-
debug " tree is: $tree"
231+
newrev=$(cache_get $rev)
232+
if [ -n "$newrev" ]; then
233+
debug " prior: $newrev"
234+
else
235+
debug " parents: $parents"
236+
newparents=$(cache_get $parents)
237+
debug " newparents: $newparents"
238+
239+
tree=$(subtree_for_commit $rev "$dir")
240+
debug " tree is: $tree"
240241

241-
# ugly. is there no better way to tell if this is a subtree
242-
# vs. a mainline commit? Does it matter?
243-
if [ -z $tree ]; then
244-
if [ -n "$newparents" ]; then
245-
cache_set $rev $rev
242+
# ugly. is there no better way to tell if this is a subtree
243+
# vs. a mainline commit? Does it matter?
244+
if [ -z $tree ]; then
245+
if [ -n "$newparents" ]; then
246+
cache_set $rev $rev
247+
fi
248+
continue
246249
fi
247-
continue
250+
251+
newrev=$(copy_or_skip "$rev" "$tree" "$newparents") || exit $?
252+
debug " newrev is: $newrev"
253+
cache_set $rev $newrev
248254
fi
249255

250-
newrev=$(copy_or_skip "$rev" "$tree" "$newparents") || exit $?
251-
debug " newrev is: $newrev"
252-
cache_set $rev $newrev
253256
cache_set latest_new $newrev
254257
cache_set latest_old $rev
255258
done || exit $?

0 commit comments

Comments
 (0)