Merge branch 'master'
commit
6eb668df76
|
@ -8,8 +8,8 @@ git-am - Apply a series of patches in a mailbox
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
'git-am' [--signoff] [--dotest=<dir>] [--utf8] [--3way] <mbox>...
|
'git-am' [--signoff] [--dotest=<dir>] [--utf8] [--binary] [--3way] <mbox>...
|
||||||
'git-am' [--skip]
|
'git-am' [--skip | --resolved]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
|
@ -31,6 +31,10 @@ OPTIONS
|
||||||
Pass `--utf8` and `--keep` flags to `git-mailinfo` (see
|
Pass `--utf8` and `--keep` flags to `git-mailinfo` (see
|
||||||
gitlink:git-mailinfo[1]).
|
gitlink:git-mailinfo[1]).
|
||||||
|
|
||||||
|
--binary::
|
||||||
|
Pass `--allow-binary-replacement` flag to `git-apply`
|
||||||
|
(see gitlink:git-apply[1]).
|
||||||
|
|
||||||
--3way::
|
--3way::
|
||||||
When the patch does not apply cleanly, fall back on
|
When the patch does not apply cleanly, fall back on
|
||||||
3-way merge, if the patch records the identity of blobs
|
3-way merge, if the patch records the identity of blobs
|
||||||
|
@ -44,6 +48,13 @@ OPTIONS
|
||||||
--interactive::
|
--interactive::
|
||||||
Run interactively, just like git-applymbox.
|
Run interactively, just like git-applymbox.
|
||||||
|
|
||||||
|
--resolved::
|
||||||
|
After a patch failure (e.g. attempting to apply
|
||||||
|
conflicting patch), the user has applied it by hand and
|
||||||
|
the index file stores the result of the application.
|
||||||
|
Make a commit using the authorship and commit log
|
||||||
|
extracted from the e-mail message and the current index
|
||||||
|
file, and continue.
|
||||||
|
|
||||||
DISCUSSION
|
DISCUSSION
|
||||||
----------
|
----------
|
||||||
|
@ -56,12 +67,9 @@ recover from this in one of two ways:
|
||||||
. skip the current one by re-running the command with '--skip'
|
. skip the current one by re-running the command with '--skip'
|
||||||
option.
|
option.
|
||||||
|
|
||||||
. hand resolve the conflict in the working directory, run 'git
|
. hand resolve the conflict in the working directory, and update
|
||||||
diff HEAD' to extract the merge result into a patch form and
|
the index file to bring it in a state that the patch should
|
||||||
replacing the patch in .dotest/patch file. After doing this,
|
have produced. Then run the command with '--resume' option.
|
||||||
run `git-reset --hard HEAD` to bring the working tree to the
|
|
||||||
state before half-applying the patch, then re-run the command
|
|
||||||
without any options.
|
|
||||||
|
|
||||||
The command refuses to process new mailboxes while `.dotest`
|
The command refuses to process new mailboxes while `.dotest`
|
||||||
directory exists, so if you decide to start over from scratch,
|
directory exists, so if you decide to start over from scratch,
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -466,7 +466,7 @@ deb: dist
|
||||||
### Cleaning rules
|
### Cleaning rules
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o mozilla-sha1/*.o ppc/*.o compat/*.o $(PROGRAMS) $(LIB_FILE)
|
rm -f *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o git $(PROGRAMS) $(LIB_FILE)
|
||||||
rm -f $(filter-out gitk,$(SCRIPTS))
|
rm -f $(filter-out gitk,$(SCRIPTS))
|
||||||
rm -f *.spec *.pyc *.pyo
|
rm -f *.spec *.pyc *.pyo
|
||||||
rm -rf $(GIT_TARNAME)
|
rm -rf $(GIT_TARNAME)
|
||||||
|
|
22
apply.c
22
apply.c
|
@ -893,12 +893,24 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
|
||||||
patchsize = parse_single_patch(buffer + offset + hdrsize, size - offset - hdrsize, patch);
|
patchsize = parse_single_patch(buffer + offset + hdrsize, size - offset - hdrsize, patch);
|
||||||
|
|
||||||
if (!patchsize) {
|
if (!patchsize) {
|
||||||
static const char binhdr[] = "Binary files ";
|
static const char *binhdr[] = {
|
||||||
|
"Binary files ",
|
||||||
|
"Files ",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
int hd = hdrsize + offset;
|
||||||
|
unsigned long llen = linelen(buffer + hd, size - hd);
|
||||||
|
|
||||||
if (sizeof(binhdr) - 1 < size - offset - hdrsize &&
|
if (!memcmp(" differ\n", buffer + hd + llen - 8, 8))
|
||||||
!memcmp(binhdr, buffer + hdrsize + offset,
|
for (i = 0; binhdr[i]; i++) {
|
||||||
sizeof(binhdr)-1))
|
int len = strlen(binhdr[i]);
|
||||||
patch->is_binary = 1;
|
if (len < size - hd &&
|
||||||
|
!memcmp(binhdr[i], buffer + hd, len)) {
|
||||||
|
patch->is_binary = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Empty patch cannot be applied if:
|
/* Empty patch cannot be applied if:
|
||||||
* - it is a binary patch and we do not do binary_replace, or
|
* - it is a binary patch and we do not do binary_replace, or
|
||||||
|
|
18
date.c
18
date.c
|
@ -34,7 +34,7 @@ static const char *month_names[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *weekday_names[] = {
|
static const char *weekday_names[] = {
|
||||||
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
|
"Sundays", "Mondays", "Tuesdays", "Wednesdays", "Thursdays", "Fridays", "Saturdays"
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -531,6 +531,22 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, int *num)
|
||||||
tl++;
|
tl++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 7; i++) {
|
||||||
|
int match = match_string(date, weekday_names[i]);
|
||||||
|
if (match >= 3) {
|
||||||
|
int diff, n = *num -1;
|
||||||
|
*num = 0;
|
||||||
|
|
||||||
|
diff = tm->tm_wday - i;
|
||||||
|
if (diff <= 0)
|
||||||
|
n++;
|
||||||
|
diff += 7*n;
|
||||||
|
|
||||||
|
update_tm(tm, diff * 24 * 60 * 60);
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (match_string(date, "months") >= 5) {
|
if (match_string(date, "months") >= 5) {
|
||||||
int n = tm->tm_mon - *num;
|
int n = tm->tm_mon - *num;
|
||||||
*num = 0;
|
*num = 0;
|
||||||
|
|
20
git-am.sh
20
git-am.sh
|
@ -4,7 +4,7 @@
|
||||||
. git-sh-setup || die "Not a git archive"
|
. git-sh-setup || die "Not a git archive"
|
||||||
|
|
||||||
usage () {
|
usage () {
|
||||||
echo >&2 "usage: $0 [--signoff] [--dotest=<dir>] [--utf8] [--3way] <mbox>"
|
echo >&2 "usage: $0 [--signoff] [--dotest=<dir>] [--utf8] [--binary] [--3way] <mbox>"
|
||||||
echo >&2 " or, when resuming"
|
echo >&2 " or, when resuming"
|
||||||
echo >&2 " $0 [--skip | --resolved]"
|
echo >&2 " $0 [--skip | --resolved]"
|
||||||
exit 1;
|
exit 1;
|
||||||
|
@ -40,7 +40,7 @@ fall_back_3way () {
|
||||||
cd "$dotest/patch-merge-tmp-dir" &&
|
cd "$dotest/patch-merge-tmp-dir" &&
|
||||||
GIT_INDEX_FILE="../patch-merge-tmp-index" \
|
GIT_INDEX_FILE="../patch-merge-tmp-index" \
|
||||||
GIT_OBJECT_DIRECTORY="$O_OBJECT" \
|
GIT_OBJECT_DIRECTORY="$O_OBJECT" \
|
||||||
git-apply --index <../patch
|
git-apply $binary --index <../patch
|
||||||
)
|
)
|
||||||
then
|
then
|
||||||
echo Using index info to reconstruct a base tree...
|
echo Using index info to reconstruct a base tree...
|
||||||
|
@ -71,7 +71,7 @@ fall_back_3way () {
|
||||||
GIT_OBJECT_DIRECTORY="$O_OBJECT" &&
|
GIT_OBJECT_DIRECTORY="$O_OBJECT" &&
|
||||||
export GIT_INDEX_FILE GIT_OBJECT_DIRECTORY &&
|
export GIT_INDEX_FILE GIT_OBJECT_DIRECTORY &&
|
||||||
git-read-tree "$base" &&
|
git-read-tree "$base" &&
|
||||||
git-apply --index &&
|
git-apply $binary --index &&
|
||||||
mv ../patch-merge-tmp-index ../patch-merge-index &&
|
mv ../patch-merge-tmp-index ../patch-merge-index &&
|
||||||
echo "$base" >../patch-merge-base
|
echo "$base" >../patch-merge-base
|
||||||
) <"$dotest/patch" 2>/dev/null && break
|
) <"$dotest/patch" 2>/dev/null && break
|
||||||
|
@ -98,7 +98,7 @@ fall_back_3way () {
|
||||||
}
|
}
|
||||||
|
|
||||||
prec=4
|
prec=4
|
||||||
dotest=.dotest sign= utf8= keep= skip= interactive= resolved=
|
dotest=.dotest sign= utf8= keep= skip= interactive= resolved= binary=
|
||||||
|
|
||||||
while case "$#" in 0) break;; esac
|
while case "$#" in 0) break;; esac
|
||||||
do
|
do
|
||||||
|
@ -113,6 +113,9 @@ do
|
||||||
--interacti|--interactiv|--interactive)
|
--interacti|--interactiv|--interactive)
|
||||||
interactive=t; shift ;;
|
interactive=t; shift ;;
|
||||||
|
|
||||||
|
-b|--b|--bi|--bin|--bina|--binar|--binary)
|
||||||
|
binary=t; shift ;;
|
||||||
|
|
||||||
-3|--3|--3w|--3wa|--3way)
|
-3|--3|--3w|--3wa|--3way)
|
||||||
threeway=t; shift ;;
|
threeway=t; shift ;;
|
||||||
-s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
|
-s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
|
||||||
|
@ -169,9 +172,10 @@ else
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# -s, -u and -k flags are kept for the resuming session after
|
# -b, -s, -u and -k flags are kept for the resuming session after
|
||||||
# a patch failure.
|
# a patch failure.
|
||||||
# -3 and -i can and must be given when resuming.
|
# -3 and -i can and must be given when resuming.
|
||||||
|
echo "$binary" >"$dotest/binary"
|
||||||
echo "$sign" >"$dotest/sign"
|
echo "$sign" >"$dotest/sign"
|
||||||
echo "$utf8" >"$dotest/utf8"
|
echo "$utf8" >"$dotest/utf8"
|
||||||
echo "$keep" >"$dotest/keep"
|
echo "$keep" >"$dotest/keep"
|
||||||
|
@ -187,6 +191,10 @@ case "$resolved" in
|
||||||
fi
|
fi
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
if test "$(cat "$dotest/binary")" = t
|
||||||
|
then
|
||||||
|
binary=--allow-binary-replacement
|
||||||
|
fi
|
||||||
if test "$(cat "$dotest/utf8")" = t
|
if test "$(cat "$dotest/utf8")" = t
|
||||||
then
|
then
|
||||||
utf8=-u
|
utf8=-u
|
||||||
|
@ -339,7 +347,7 @@ do
|
||||||
|
|
||||||
case "$resolved" in
|
case "$resolved" in
|
||||||
'')
|
'')
|
||||||
git-apply --index "$dotest/patch"
|
git-apply $binary --index "$dotest/patch"
|
||||||
apply_status=$?
|
apply_status=$?
|
||||||
;;
|
;;
|
||||||
t)
|
t)
|
||||||
|
|
|
@ -30,6 +30,24 @@ See man (1) git-archimport for more details.
|
||||||
|
|
||||||
Add print in front of the shell commands invoked via backticks.
|
Add print in front of the shell commands invoked via backticks.
|
||||||
|
|
||||||
|
=head1 Devel Notes
|
||||||
|
|
||||||
|
There are several places where Arch and git terminology are intermixed
|
||||||
|
and potentially confused.
|
||||||
|
|
||||||
|
The notion of a "branch" in git is approximately equivalent to
|
||||||
|
a "archive/category--branch--version" in Arch. Also, it should be noted
|
||||||
|
that the "--branch" portion of "archive/category--branch--version" is really
|
||||||
|
optional in Arch although not many people (nor tools!) seem to know this.
|
||||||
|
This means that "archive/category--version" is also a valid "branch"
|
||||||
|
in git terms.
|
||||||
|
|
||||||
|
We always refer to Arch names by their fully qualified variant (which
|
||||||
|
means the "archive" name is prefixed.
|
||||||
|
|
||||||
|
For people unfamiliar with Arch, an "archive" is the term for "repository",
|
||||||
|
and can contain multiple, unrelated branches.
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
|
@ -52,14 +70,14 @@ $ENV{'TZ'}="UTC";
|
||||||
|
|
||||||
my $git_dir = $ENV{"GIT_DIR"} || ".git";
|
my $git_dir = $ENV{"GIT_DIR"} || ".git";
|
||||||
$ENV{"GIT_DIR"} = $git_dir;
|
$ENV{"GIT_DIR"} = $git_dir;
|
||||||
|
my $ptag_dir = "$git_dir/archimport/tags";
|
||||||
|
|
||||||
our($opt_h,$opt_v, $opt_T,
|
our($opt_h,$opt_v, $opt_T,$opt_t,$opt_o);
|
||||||
$opt_C,$opt_t);
|
|
||||||
|
|
||||||
sub usage() {
|
sub usage() {
|
||||||
print STDERR <<END;
|
print STDERR <<END;
|
||||||
Usage: ${\basename $0} # fetch/update GIT from Arch
|
Usage: ${\basename $0} # fetch/update GIT from Arch
|
||||||
[ -h ] [ -v ] [ -T ] [ -t tempdir ]
|
[ -o ] [ -h ] [ -v ] [ -T ] [ -t tempdir ]
|
||||||
repository/arch-branch [ repository/arch-branch] ...
|
repository/arch-branch [ repository/arch-branch] ...
|
||||||
END
|
END
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -195,25 +213,68 @@ unless (-d $git_dir) { # initial import
|
||||||
opendir(DIR, "$git_dir/archimport/tags")
|
opendir(DIR, "$git_dir/archimport/tags")
|
||||||
|| die "can't opendir: $!";
|
|| die "can't opendir: $!";
|
||||||
while (my $file = readdir(DIR)) {
|
while (my $file = readdir(DIR)) {
|
||||||
# skip non-interesting-files
|
# skip non-interesting-files
|
||||||
next unless -f "$git_dir/archimport/tags/$file";
|
next unless -f "$ptag_dir/$file";
|
||||||
next if $file =~ m/--base-0$/; # don't care for base-0
|
|
||||||
|
# convert first '--' to '/' from old git-archimport to use
|
||||||
|
# as an archivename/c--b--v private tag
|
||||||
|
if ($file !~ m!,!) {
|
||||||
|
my $oldfile = $file;
|
||||||
|
$file =~ s!--!,!;
|
||||||
|
print STDERR "converting old tag $oldfile to $file\n";
|
||||||
|
rename("$ptag_dir/$oldfile", "$ptag_dir/$file") or die $!;
|
||||||
|
}
|
||||||
my $sha = ptag($file);
|
my $sha = ptag($file);
|
||||||
chomp $sha;
|
chomp $sha;
|
||||||
# reconvert the 3rd '--' sequence from the end
|
|
||||||
# into a slash
|
|
||||||
# $file = reverse $file;
|
|
||||||
# $file =~ s!^(.+?--.+?--.+?--.+?)--(.+)$!$1/$2!;
|
|
||||||
# $file = reverse $file;
|
|
||||||
$rptags{$sha} = $file;
|
$rptags{$sha} = $file;
|
||||||
}
|
}
|
||||||
closedir DIR;
|
closedir DIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
# process patchsets
|
# process patchsets
|
||||||
foreach my $ps (@psets) {
|
# extract the Arch repository name (Arch "archive" in Arch-speak)
|
||||||
|
sub extract_reponame {
|
||||||
|
my $fq_cvbr = shift; # archivename/[[[[category]branch]version]revision]
|
||||||
|
return (split(/\//, $fq_cvbr))[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
sub extract_versionname {
|
||||||
|
my $name = shift;
|
||||||
|
$name =~ s/--(?:patch|version(?:fix)?|base)-\d+$//;
|
||||||
|
return $name;
|
||||||
|
}
|
||||||
|
|
||||||
$ps->{branch} = branchname($ps->{id});
|
# convert a fully-qualified revision or version to a unique dirname:
|
||||||
|
# normalperson@yhbt.net-05/mpd--uclinux--1--patch-2
|
||||||
|
# becomes: normalperson@yhbt.net-05,mpd--uclinux--1
|
||||||
|
#
|
||||||
|
# the git notion of a branch is closer to
|
||||||
|
# archive/category--branch--version than archive/category--branch, so we
|
||||||
|
# use this to convert to git branch names.
|
||||||
|
# Also, keep archive names but replace '/' with ',' since it won't require
|
||||||
|
# subdirectories, and is safer than swapping '--' which could confuse
|
||||||
|
# reverse-mapping when dealing with bastard branches that
|
||||||
|
# are just archive/category--version (no --branch)
|
||||||
|
sub tree_dirname {
|
||||||
|
my $revision = shift;
|
||||||
|
my $name = extract_versionname($revision);
|
||||||
|
$name =~ s#/#,#;
|
||||||
|
return $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
# old versions of git-archimport just use the <category--branch> part:
|
||||||
|
sub old_style_branchname {
|
||||||
|
my $id = shift;
|
||||||
|
my $ret = safe_pipe_capture($TLA,'parse-package-name','-p',$id);
|
||||||
|
chomp $ret;
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
*git_branchname = $opt_o ? *old_style_branchname : *tree_dirname;
|
||||||
|
|
||||||
|
# process patchsets
|
||||||
|
foreach my $ps (@psets) {
|
||||||
|
$ps->{branch} = git_branchname($ps->{id});
|
||||||
|
|
||||||
#
|
#
|
||||||
# ensure we have a clean state
|
# ensure we have a clean state
|
||||||
|
@ -424,16 +485,9 @@ foreach my $ps (@psets) {
|
||||||
$opt_v && print " + parents: $par \n";
|
$opt_v && print " + parents: $par \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub branchname {
|
|
||||||
my $id = shift;
|
|
||||||
$id =~ s#^.+?/##;
|
|
||||||
my @parts = split(m/--/, $id);
|
|
||||||
return join('--', @parts[0..1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub apply_import {
|
sub apply_import {
|
||||||
my $ps = shift;
|
my $ps = shift;
|
||||||
my $bname = branchname($ps->{id});
|
my $bname = git_branchname($ps->{id});
|
||||||
|
|
||||||
`mkdir -p $tmp`;
|
`mkdir -p $tmp`;
|
||||||
|
|
||||||
|
@ -581,19 +635,24 @@ sub parselog {
|
||||||
# write/read a tag
|
# write/read a tag
|
||||||
sub tag {
|
sub tag {
|
||||||
my ($tag, $commit) = @_;
|
my ($tag, $commit) = @_;
|
||||||
$tag =~ s|/|--|g;
|
|
||||||
$tag = shell_quote($tag);
|
if ($opt_o) {
|
||||||
|
$tag =~ s|/|--|g;
|
||||||
|
} else {
|
||||||
|
# don't use subdirs for tags yet, it could screw up other porcelains
|
||||||
|
$tag =~ s|/|,|g;
|
||||||
|
}
|
||||||
|
|
||||||
if ($commit) {
|
if ($commit) {
|
||||||
open(C,">$git_dir/refs/tags/$tag")
|
open(C,">","$git_dir/refs/tags/$tag")
|
||||||
or die "Cannot create tag $tag: $!\n";
|
or die "Cannot create tag $tag: $!\n";
|
||||||
print C "$commit\n"
|
print C "$commit\n"
|
||||||
or die "Cannot write tag $tag: $!\n";
|
or die "Cannot write tag $tag: $!\n";
|
||||||
close(C)
|
close(C)
|
||||||
or die "Cannot write tag $tag: $!\n";
|
or die "Cannot write tag $tag: $!\n";
|
||||||
print " * Created tag ' $tag' on '$commit'\n" if $opt_v;
|
print " * Created tag '$tag' on '$commit'\n" if $opt_v;
|
||||||
} else { # read
|
} else { # read
|
||||||
open(C,"<$git_dir/refs/tags/$tag")
|
open(C,"<","$git_dir/refs/tags/$tag")
|
||||||
or die "Cannot read tag $tag: $!\n";
|
or die "Cannot read tag $tag: $!\n";
|
||||||
$commit = <C>;
|
$commit = <C>;
|
||||||
chomp $commit;
|
chomp $commit;
|
||||||
|
@ -608,15 +667,16 @@ sub tag {
|
||||||
# reads fail softly if the tag isn't there
|
# reads fail softly if the tag isn't there
|
||||||
sub ptag {
|
sub ptag {
|
||||||
my ($tag, $commit) = @_;
|
my ($tag, $commit) = @_;
|
||||||
$tag =~ s|/|--|g;
|
|
||||||
$tag = shell_quote($tag);
|
# don't use subdirs for tags yet, it could screw up other porcelains
|
||||||
|
$tag =~ s|/|,|g;
|
||||||
|
|
||||||
unless (-d "$git_dir/archimport/tags") {
|
my $tag_file = "$ptag_dir/$tag";
|
||||||
mkpath("$git_dir/archimport/tags");
|
my $tag_branch_dir = dirname($tag_file);
|
||||||
}
|
mkpath($tag_branch_dir) unless (-d $tag_branch_dir);
|
||||||
|
|
||||||
if ($commit) { # write
|
if ($commit) { # write
|
||||||
open(C,">$git_dir/archimport/tags/$tag")
|
open(C,">",$tag_file)
|
||||||
or die "Cannot create tag $tag: $!\n";
|
or die "Cannot create tag $tag: $!\n";
|
||||||
print C "$commit\n"
|
print C "$commit\n"
|
||||||
or die "Cannot write tag $tag: $!\n";
|
or die "Cannot write tag $tag: $!\n";
|
||||||
|
@ -626,10 +686,10 @@ sub ptag {
|
||||||
unless $tag =~ m/--base-0$/;
|
unless $tag =~ m/--base-0$/;
|
||||||
} else { # read
|
} else { # read
|
||||||
# if the tag isn't there, return 0
|
# if the tag isn't there, return 0
|
||||||
unless ( -s "$git_dir/archimport/tags/$tag") {
|
unless ( -s $tag_file) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
open(C,"<$git_dir/archimport/tags/$tag")
|
open(C,"<",$tag_file)
|
||||||
or die "Cannot read tag $tag: $!\n";
|
or die "Cannot read tag $tag: $!\n";
|
||||||
$commit = <C>;
|
$commit = <C>;
|
||||||
chomp $commit;
|
chomp $commit;
|
||||||
|
@ -662,7 +722,7 @@ sub find_parents {
|
||||||
# simple loop to split the merges
|
# simple loop to split the merges
|
||||||
# per branch
|
# per branch
|
||||||
foreach my $merge (@{$ps->{merges}}) {
|
foreach my $merge (@{$ps->{merges}}) {
|
||||||
my $branch = branchname($merge);
|
my $branch = git_branchname($merge);
|
||||||
unless (defined $branches{$branch} ){
|
unless (defined $branches{$branch} ){
|
||||||
$branches{$branch} = [];
|
$branches{$branch} = [];
|
||||||
}
|
}
|
||||||
|
@ -686,7 +746,13 @@ sub find_parents {
|
||||||
next unless -e "$git_dir/refs/heads/$branch";
|
next unless -e "$git_dir/refs/heads/$branch";
|
||||||
|
|
||||||
my $mergebase = `git-merge-base $branch $ps->{branch}`;
|
my $mergebase = `git-merge-base $branch $ps->{branch}`;
|
||||||
die "Cannot find merge base for $branch and $ps->{branch}" if $?;
|
if ($?) {
|
||||||
|
# Don't die here, Arch supports one-way cherry-picking
|
||||||
|
# between branches with no common base (or any relationship
|
||||||
|
# at all beforehand)
|
||||||
|
warn "Cannot find merge base for $branch and $ps->{branch}";
|
||||||
|
next;
|
||||||
|
}
|
||||||
chomp $mergebase;
|
chomp $mergebase;
|
||||||
|
|
||||||
# now walk up to the mergepoint collecting what patches we have
|
# now walk up to the mergepoint collecting what patches we have
|
||||||
|
@ -779,12 +845,7 @@ sub commitid2pset {
|
||||||
chomp $commitid;
|
chomp $commitid;
|
||||||
my $name = $rptags{$commitid}
|
my $name = $rptags{$commitid}
|
||||||
|| die "Cannot find reverse tag mapping for $commitid";
|
|| die "Cannot find reverse tag mapping for $commitid";
|
||||||
# the keys in %rptag are slightly munged; unmunge
|
$name =~ s|,|/|;
|
||||||
# reconvert the 3rd '--' sequence from the end
|
|
||||||
# into a slash
|
|
||||||
$name = reverse $name;
|
|
||||||
$name =~ s!^(.+?--.+?--.+?--.+?)--(.+)$!$1/$2!;
|
|
||||||
$name = reverse $name;
|
|
||||||
my $ps = $psets{$name}
|
my $ps = $psets{$name}
|
||||||
|| (print Dumper(sort keys %psets)) && die "Cannot find patchset for $name";
|
|| (print Dumper(sort keys %psets)) && die "Cannot find patchset for $name";
|
||||||
return $ps;
|
return $ps;
|
||||||
|
|
|
@ -11,7 +11,7 @@ do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-n) no_update_info=t ;;
|
-n) no_update_info=t ;;
|
||||||
-a) all_into_one=t ;;
|
-a) all_into_one=t ;;
|
||||||
-d) remove_redandant=t ;;
|
-d) remove_redundant=t ;;
|
||||||
-l) local=t ;;
|
-l) local=t ;;
|
||||||
*) break ;;
|
*) break ;;
|
||||||
esac
|
esac
|
||||||
|
@ -42,7 +42,7 @@ name=$(git-rev-list --objects $rev_list $(git-rev-parse $rev_parse) |
|
||||||
exit 1
|
exit 1
|
||||||
if [ -z "$name" ]; then
|
if [ -z "$name" ]; then
|
||||||
echo Nothing new to pack.
|
echo Nothing new to pack.
|
||||||
if test "$remove_redandant" = t ; then
|
if test "$remove_redundant" = t ; then
|
||||||
echo "Removing redundant packs."
|
echo "Removing redundant packs."
|
||||||
sync
|
sync
|
||||||
redundant=$(git-pack-redundant --all)
|
redundant=$(git-pack-redundant --all)
|
||||||
|
@ -60,7 +60,7 @@ mv .tmp-pack-$name.pack "$PACKDIR/pack-$name.pack" &&
|
||||||
mv .tmp-pack-$name.idx "$PACKDIR/pack-$name.idx" ||
|
mv .tmp-pack-$name.idx "$PACKDIR/pack-$name.idx" ||
|
||||||
exit
|
exit
|
||||||
|
|
||||||
if test "$remove_redandant" = t
|
if test "$remove_redundant" = t
|
||||||
then
|
then
|
||||||
sync
|
sync
|
||||||
redundant=$(git-pack-redundant --all)
|
redundant=$(git-pack-redundant --all)
|
||||||
|
|
|
@ -33,6 +33,7 @@ struct pack_list {
|
||||||
struct pll {
|
struct pll {
|
||||||
struct pll *next;
|
struct pll *next;
|
||||||
struct pack_list *pl;
|
struct pack_list *pl;
|
||||||
|
size_t pl_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void llist_free(struct llist *list)
|
inline void llist_free(struct llist *list)
|
||||||
|
@ -249,18 +250,45 @@ void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pll_insert(struct pll **pll, struct pll **hint_table)
|
||||||
|
{
|
||||||
|
struct pll *prev;
|
||||||
|
int i = (*pll)->pl_size - 1;
|
||||||
|
|
||||||
|
if (hint_table[i] == NULL) {
|
||||||
|
hint_table[i--] = *pll;
|
||||||
|
for (; i >= 0; --i) {
|
||||||
|
if (hint_table[i] != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (hint_table[i] == NULL) /* no elements in list */
|
||||||
|
die("Why did this happen?");
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = hint_table[i];
|
||||||
|
while (prev->next && prev->next->pl_size < (*pll)->pl_size)
|
||||||
|
prev = prev->next;
|
||||||
|
|
||||||
|
(*pll)->next = prev->next;
|
||||||
|
prev->next = *pll;
|
||||||
|
}
|
||||||
|
|
||||||
/* all the permutations have to be free()d at the same time,
|
/* all the permutations have to be free()d at the same time,
|
||||||
* since they refer to each other
|
* since they refer to each other
|
||||||
*/
|
*/
|
||||||
struct pll * get_all_permutations(struct pack_list *list)
|
struct pll * get_all_permutations(struct pack_list *list)
|
||||||
{
|
{
|
||||||
struct pll *subset, *pll, *new_pll = NULL; /*silence warning*/
|
struct pll *subset, *pll, *new_pll = NULL; /*silence warning*/
|
||||||
|
static struct pll **hint = NULL;
|
||||||
|
if (hint == NULL)
|
||||||
|
hint = xcalloc(pack_list_size(list), sizeof(struct pll *));
|
||||||
|
|
||||||
if (list == NULL)
|
if (list == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (list->next == NULL) {
|
if (list->next == NULL) {
|
||||||
new_pll = xmalloc(sizeof(struct pll));
|
new_pll = xmalloc(sizeof(struct pll));
|
||||||
|
hint[0] = new_pll;
|
||||||
new_pll->next = NULL;
|
new_pll->next = NULL;
|
||||||
new_pll->pl = list;
|
new_pll->pl = list;
|
||||||
return new_pll;
|
return new_pll;
|
||||||
|
@ -268,24 +296,30 @@ struct pll * get_all_permutations(struct pack_list *list)
|
||||||
|
|
||||||
pll = subset = get_all_permutations(list->next);
|
pll = subset = get_all_permutations(list->next);
|
||||||
while (pll) {
|
while (pll) {
|
||||||
|
if (pll->pl->pack == list->pack) {
|
||||||
|
pll = pll->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
new_pll = xmalloc(sizeof(struct pll));
|
new_pll = xmalloc(sizeof(struct pll));
|
||||||
new_pll->next = pll->next;
|
|
||||||
pll->next = new_pll;
|
|
||||||
|
|
||||||
new_pll->pl = xmalloc(sizeof(struct pack_list));
|
new_pll->pl = xmalloc(sizeof(struct pack_list));
|
||||||
memcpy(new_pll->pl, list, sizeof(struct pack_list));
|
memcpy(new_pll->pl, list, sizeof(struct pack_list));
|
||||||
new_pll->pl->next = pll->pl;
|
new_pll->pl->next = pll->pl;
|
||||||
|
new_pll->pl_size = pll->pl_size + 1;
|
||||||
|
|
||||||
|
pll_insert(&new_pll, hint);
|
||||||
|
|
||||||
pll = new_pll->next;
|
pll = pll->next;
|
||||||
}
|
}
|
||||||
/* add ourself to the end */
|
/* add ourself */
|
||||||
new_pll->next = xmalloc(sizeof(struct pll));
|
new_pll = xmalloc(sizeof(struct pll));
|
||||||
new_pll->next->pl = xmalloc(sizeof(struct pack_list));
|
new_pll->pl = xmalloc(sizeof(struct pack_list));
|
||||||
new_pll->next->next = NULL;
|
memcpy(new_pll->pl, list, sizeof(struct pack_list));
|
||||||
memcpy(new_pll->next->pl, list, sizeof(struct pack_list));
|
new_pll->pl->next = NULL;
|
||||||
new_pll->next->pl->next = NULL;
|
new_pll->pl_size = 1;
|
||||||
|
pll_insert(&new_pll, hint);
|
||||||
|
|
||||||
return subset;
|
return hint[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
int is_superset(struct pack_list *pl, struct llist *list)
|
int is_superset(struct pack_list *pl, struct llist *list)
|
||||||
|
@ -401,6 +435,8 @@ void minimize(struct pack_list **min)
|
||||||
/* find the permutations which contain all missing objects */
|
/* find the permutations which contain all missing objects */
|
||||||
perm_all = perm = get_all_permutations(non_unique);
|
perm_all = perm = get_all_permutations(non_unique);
|
||||||
while (perm) {
|
while (perm) {
|
||||||
|
if (perm_ok && perm->pl_size > perm_ok->pl_size)
|
||||||
|
break; /* ignore all larger permutations */
|
||||||
if (is_superset(perm->pl, missing)) {
|
if (is_superset(perm->pl, missing)) {
|
||||||
new_perm = xmalloc(sizeof(struct pll));
|
new_perm = xmalloc(sizeof(struct pll));
|
||||||
new_perm->pl = perm->pl;
|
new_perm->pl = perm->pl;
|
||||||
|
|
Loading…
Reference in New Issue