split a set of changesets up based on filesets
Harvey Chapman
hchapman-hg at 3gfp.com
Wed Jan 14 15:17:15 UTC 2015
> On Jan 14, 2015, at 7:23 AM, Matthew Turk <matthewturk at gmail.com> wrote:
>
> I have a big set of monolithic changes that I'd like to split up into multiple changes based on file patterns. I'm happy to use evolve-aware commands and functions, but I'm not sure how to split up a changeset like that.
>
> Given a revision specifier, is it possible to apply all the changes in a squashed way but *only* to the files specified by a given fileset?
You might be able to adapt the following to do what you want. It creates an original repo with files a-f which are all modified in each commit. It then splits the changes into sets a-c and d-f into two separate branches starting at an arbitrary revision in the history. It uses convert with filemap and splicemap to do this. If the conversion below using the splicemap doesn’t work for you, you could use the new repo to generate diffs to import into a copy of your original repo.
From this:
5: adding 6 a b c d e f
4: adding 5 a b c d e f
3: adding 4 a b c d e f
2: adding 3 a b c d e f
1: adding 2 a b c d e f
0: adding 1 a b c d e f
To this:
o 8: adding 6 d e f
|
o 7: adding 5 d e f
|
o 6: adding 4 d e f
|
| o 5: adding 6 a b c
| |
| o 4: adding 5 a b c
| |
| o 3: adding 4 a b c
|/
o 2: adding 3 a b c d e f
|
o 1: adding 2 a b c d e f
|
o 0: adding 1 a b c d e f
#!/bin/sh
# Helpers
LOG_TEMPLATE="\"{pad(rev,'2',' ','1')}: {pad(desc,'30')} {files}\n\""
alias brief_log="hg log --template $LOG_TEMPLATE -R"
alias brief_graph_log="hg log --graph --template $LOG_TEMPLATE -R"
# Uasge: hash_for_rev(repo, revnum)
hash_for_rev() { hg -R "$1" log -r "$2" --template '{node}'; }
# Cleanup
rm -rf new orig filemap splicemap
# Create original repo modifying files a-f in each revision
hg init orig
cd orig
touch a b c d e f
for n in `seq 1 6`; do for file in *; do echo $n >> $file; done; hg ci -Am "adding $n"; done
brief_log
cd ..
# Split the revisions into two sets of files starting
# with rev 2 (arbitrarily chosen)
hg convert -r 2 orig new
# Save the REVMAP generated by convert
cp new/.hg/shamap .
# Create a filemap excluding d-f
echo 'exclude d' > filemap
echo 'exclude e' >> filemap
echo 'exclude f' >> filemap
# Convert remaining revisions filtering out d-f
hg convert --filemap filemap orig new
# Create a splicemap to put orig:3 on top of new:2
echo $(hash_for_rev orig 3) $(hash_for_rev new 2) > splicemap
# Convert the same "remaining revisions" from above using splicemap
# and the inverse set of files. We also have to use the REVMAP file from
# earlier or else convert will (correctly) think that we've already
# converted the "remaining revisions"
sed 's,ex,in,' < filemap > filemap_inverted
hg convert --filemap filemap_inverted --splicemap splicemap orig new shamap
brief_graph_log new
More information about the Mercurial
mailing list