Merge branch 'master'
This commit is contained in:
commit
77131db585
4
.gitignore
vendored
4
.gitignore
vendored
@ -19,6 +19,7 @@ git-commit
|
|||||||
git-commit-tree
|
git-commit-tree
|
||||||
git-convert-objects
|
git-convert-objects
|
||||||
git-count-objects
|
git-count-objects
|
||||||
|
git-cvsexportcommit
|
||||||
git-cvsimport
|
git-cvsimport
|
||||||
git-daemon
|
git-daemon
|
||||||
git-diff
|
git-diff
|
||||||
@ -36,6 +37,7 @@ git-get-tar-commit-id
|
|||||||
git-grep
|
git-grep
|
||||||
git-hash-object
|
git-hash-object
|
||||||
git-http-fetch
|
git-http-fetch
|
||||||
|
git-http-push
|
||||||
git-index-pack
|
git-index-pack
|
||||||
git-init-db
|
git-init-db
|
||||||
git-local-fetch
|
git-local-fetch
|
||||||
@ -107,6 +109,8 @@ git-verify-tag
|
|||||||
git-whatchanged
|
git-whatchanged
|
||||||
git-write-tree
|
git-write-tree
|
||||||
git-core-*/?*
|
git-core-*/?*
|
||||||
|
test-date
|
||||||
|
test-delta
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
*.dsc
|
*.dsc
|
||||||
*.deb
|
*.deb
|
||||||
|
1
Documentation/.gitignore
vendored
1
Documentation/.gitignore
vendored
@ -3,3 +3,4 @@
|
|||||||
*.1
|
*.1
|
||||||
*.7
|
*.7
|
||||||
howto-index.txt
|
howto-index.txt
|
||||||
|
doc.dep
|
||||||
|
@ -53,21 +53,19 @@ install: man
|
|||||||
#
|
#
|
||||||
# Determine "include::" file references in asciidoc files.
|
# Determine "include::" file references in asciidoc files.
|
||||||
#
|
#
|
||||||
TEXTFILES = $(wildcard *.txt)
|
TEXTFILES = $(wildcard git-*.txt)
|
||||||
DEPFILES = $(TEXTFILES:%.txt=%.dep)
|
doc.dep : $(TEXTFILES) build-docdep.perl
|
||||||
|
rm -f $@+ $@
|
||||||
|
perl ./build-docdep.perl >$@+
|
||||||
|
mv $@+ $@
|
||||||
|
|
||||||
%.dep : %.txt
|
-include doc.dep
|
||||||
@rm -f $@
|
|
||||||
@$(foreach dep, $(shell grep include:: $< | sed -e 's/include::/ /' -e 's/\[\]//'), \
|
|
||||||
echo $(<:%.txt=%.html) $(<:%.txt=%.1) : $(dep) >> $@; )
|
|
||||||
|
|
||||||
-include $(DEPFILES)
|
|
||||||
|
|
||||||
git.7: ../README
|
git.7: ../README
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.xml *.html *.1 *.7 howto-index.txt howto/*.html *.dep
|
rm -f *.xml *.html *.1 *.7 howto-index.txt howto/*.html doc.dep
|
||||||
|
|
||||||
%.html : %.txt
|
%.html : %.txt
|
||||||
asciidoc -b xhtml11 -d manpage -f asciidoc.conf $<
|
asciidoc -b xhtml11 -d manpage -f asciidoc.conf $<
|
||||||
|
28
Documentation/build-docdep.perl
Executable file
28
Documentation/build-docdep.perl
Executable file
@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
my %include = ();
|
||||||
|
|
||||||
|
for my $text (<git-*.txt>) {
|
||||||
|
open I, '<', $text || die "cannot read: $text";
|
||||||
|
(my $base = $text) =~ s/\.txt$//;
|
||||||
|
while (<I>) {
|
||||||
|
if (/^include::/) {
|
||||||
|
chomp;
|
||||||
|
s/^include::\s*//;
|
||||||
|
s/\[\]//;
|
||||||
|
$include{$base}{$_} = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close I;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Do we care about chained includes???
|
||||||
|
|
||||||
|
while (my ($base, $included) = each %include) {
|
||||||
|
my ($suffix) = '1';
|
||||||
|
if ($base eq 'git') {
|
||||||
|
$suffix = '7'; # yuck...
|
||||||
|
}
|
||||||
|
print "$base.html $base.$suffix : ", join(" ", keys %$included), "\n";
|
||||||
|
}
|
||||||
|
|
56
Documentation/git-cvsexportcommit.txt
Normal file
56
Documentation/git-cvsexportcommit.txt
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
git-cvsexportcommit(1)
|
||||||
|
======================
|
||||||
|
|
||||||
|
NAME
|
||||||
|
----
|
||||||
|
git-cvsexportcommit - Export a commit to a CVS checkout
|
||||||
|
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
--------
|
||||||
|
git-cvsapplycommmit.perl
|
||||||
|
[ -h ] [ -v ] [ -c ] [ -p ] [PARENTCOMMIT] COMMITID
|
||||||
|
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
-----------
|
||||||
|
Exports a commit from GIT to a CVS checkout, making it easier
|
||||||
|
to merge patches from a git repository into a CVS repository.
|
||||||
|
|
||||||
|
Execute it from the root of the CVS working copy. GIT_DIR must be defined.
|
||||||
|
|
||||||
|
It does its best to do the safe thing, it will check that the files are
|
||||||
|
unchanged and up to date in the CVS checkout, and it will not autocommit
|
||||||
|
by default.
|
||||||
|
|
||||||
|
Supports file additions, removals, and commits that affect binary files.
|
||||||
|
|
||||||
|
If the commit is a merge commit, you must tell git-cvsapplycommit what parent
|
||||||
|
should the changeset be done against.
|
||||||
|
|
||||||
|
OPTIONS
|
||||||
|
-------
|
||||||
|
|
||||||
|
-c::
|
||||||
|
Commit automatically if the patch applied cleanly. It will not
|
||||||
|
commit if any hunks fail to apply or there were other problems.
|
||||||
|
|
||||||
|
-p::
|
||||||
|
Be pedantic (paranoid) when applying patches. Invokes patch with
|
||||||
|
--fuzz=0
|
||||||
|
|
||||||
|
-v::
|
||||||
|
Verbose.
|
||||||
|
|
||||||
|
Author
|
||||||
|
------
|
||||||
|
Written by Martin Langhoff <martin@catalyst.net.nz>
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
--------------
|
||||||
|
Documentation by Martin Langhoff <martin@catalyst.net.nz>
|
||||||
|
|
||||||
|
GIT
|
||||||
|
---
|
||||||
|
Part of the gitlink:git[7] suite
|
||||||
|
|
@ -63,7 +63,7 @@ And then, you can just remove the broken branch if you decide you really
|
|||||||
don't want it:
|
don't want it:
|
||||||
|
|
||||||
# remove 'broken' branch
|
# remove 'broken' branch
|
||||||
rm .git/refs/heads/broken
|
git branch -d broken
|
||||||
|
|
||||||
# Prune old objects if you're really really sure
|
# Prune old objects if you're really really sure
|
||||||
git prune
|
git prune
|
||||||
|
@ -153,7 +153,8 @@ Everything is in the good order. I do not need the temporary branch
|
|||||||
nor tag anymore, so remove them:
|
nor tag anymore, so remove them:
|
||||||
|
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
$ rm -f .git/refs/tags/pu-anchor .git/refs/heads/revert-c99
|
$ rm -f .git/refs/tags/pu-anchor
|
||||||
|
$ git branch -d revert-c99
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
It was an emergency fix, so we might as well merge it into the
|
It was an emergency fix, so we might as well merge it into the
|
||||||
|
@ -166,7 +166,7 @@ output from:
|
|||||||
|
|
||||||
is empty. At this point the branch can be deleted:
|
is empty. At this point the branch can be deleted:
|
||||||
|
|
||||||
$ rm .git/refs/heads/branchname
|
$ git branch -d branchname
|
||||||
|
|
||||||
Some changes are so trivial that it is not necessary to create a separate
|
Some changes are so trivial that it is not necessary to create a separate
|
||||||
branch and then merge into each of the test and release branches. For
|
branch and then merge into each of the test and release branches. For
|
||||||
|
2
Makefile
2
Makefile
@ -93,7 +93,7 @@ SCRIPT_SH = \
|
|||||||
SCRIPT_PERL = \
|
SCRIPT_PERL = \
|
||||||
git-archimport.perl git-cvsimport.perl git-relink.perl \
|
git-archimport.perl git-cvsimport.perl git-relink.perl \
|
||||||
git-rename.perl git-shortlog.perl git-fmt-merge-msg.perl \
|
git-rename.perl git-shortlog.perl git-fmt-merge-msg.perl \
|
||||||
git-svnimport.perl git-mv.perl
|
git-svnimport.perl git-mv.perl git-cvsexportcommit.perl
|
||||||
|
|
||||||
SCRIPT_PYTHON = \
|
SCRIPT_PYTHON = \
|
||||||
git-merge-recursive.py
|
git-merge-recursive.py
|
||||||
|
225
git-cvsexportcommit.perl
Executable file
225
git-cvsexportcommit.perl
Executable file
@ -0,0 +1,225 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use Getopt::Std;
|
||||||
|
use File::Temp qw(tempdir);
|
||||||
|
use Data::Dumper;
|
||||||
|
|
||||||
|
unless ($ENV{GIT_DIR} && -r $ENV{GIT_DIR}){
|
||||||
|
die "GIT_DIR is not defined or is unreadable";
|
||||||
|
}
|
||||||
|
|
||||||
|
our ($opt_h, $opt_p, $opt_v, $opt_c );
|
||||||
|
|
||||||
|
getopt('hpvc');
|
||||||
|
|
||||||
|
$opt_h && usage();
|
||||||
|
|
||||||
|
die "Need at least one commit identifier!" unless @ARGV;
|
||||||
|
|
||||||
|
# setup a tempdir
|
||||||
|
our ($tmpdir, $tmpdirname) = tempdir('git-cvsapplycommit-XXXXXX',
|
||||||
|
TMPDIR => 1,
|
||||||
|
CLEANUP => 1);
|
||||||
|
|
||||||
|
print Dumper(@ARGV);
|
||||||
|
# resolve target commit
|
||||||
|
my $commit;
|
||||||
|
$commit = pop @ARGV;
|
||||||
|
$commit = `git-rev-parse --verify "$commit"^0`;
|
||||||
|
chomp $commit;
|
||||||
|
if ($?) {
|
||||||
|
die "The commit reference $commit did not resolve!";
|
||||||
|
}
|
||||||
|
|
||||||
|
# resolve what parent we want
|
||||||
|
my $parent;
|
||||||
|
if (@ARGV) {
|
||||||
|
$parent = pop @ARGV;
|
||||||
|
$parent = `git-rev-parse --verify "$parent"^0"`;
|
||||||
|
chomp $parent;
|
||||||
|
if ($?) {
|
||||||
|
die "The parent reference did not resolve!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# find parents from the commit itself
|
||||||
|
my @commit = `git-cat-file commit $commit`;
|
||||||
|
my @parents;
|
||||||
|
foreach my $p (@commit) {
|
||||||
|
if ($p =~ m/^$/) { # end of commit headers, we're done
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
if ($p =~ m/^parent (\w{40})$/) { # found a parent
|
||||||
|
push @parents, $1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($parent) {
|
||||||
|
# double check that it's a valid parent
|
||||||
|
foreach my $p (@parents) {
|
||||||
|
my $found;
|
||||||
|
if ($p eq $parent) {
|
||||||
|
$found = 1;
|
||||||
|
last;
|
||||||
|
}; # found it
|
||||||
|
die "Did not find $parent in the parents for this commit!";
|
||||||
|
s }
|
||||||
|
} else { # we don't have a parent from the cmdline...
|
||||||
|
if (@parents == 1) { # it's safe to get it from the commit
|
||||||
|
$parent = $parents[0];
|
||||||
|
} else { # or perhaps not!
|
||||||
|
die "This commit has more than one parent -- please name the parent you want to use explicitly";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$opt_v && print "Applying to CVS commit $commit from parent $parent\n";
|
||||||
|
|
||||||
|
# grab the commit message
|
||||||
|
`git-cat-file commit $commit | sed -e '1,/^\$/d' > .msg`;
|
||||||
|
$? && die "Error extraction the commit message";
|
||||||
|
|
||||||
|
my (@afiles, @dfiles, @mfiles);
|
||||||
|
my @files = `git-diff-tree -r $parent $commit`;
|
||||||
|
print @files;
|
||||||
|
$? && die "Error in git-diff-tree";
|
||||||
|
foreach my $f (@files) {
|
||||||
|
chomp $f;
|
||||||
|
my @fields = split(m/\s+/, $f);
|
||||||
|
if ($fields[4] eq 'A') {
|
||||||
|
push @afiles, $fields[5];
|
||||||
|
}
|
||||||
|
if ($fields[4] eq 'M') {
|
||||||
|
push @mfiles, $fields[5];
|
||||||
|
}
|
||||||
|
if ($fields[4] eq 'R') {
|
||||||
|
push @dfiles, $fields[5];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$opt_v && print "The commit affects:\n ";
|
||||||
|
$opt_v && print join ("\n ", @afiles,@mfiles,@dfiles) . "\n\n";
|
||||||
|
undef @files; # don't need it anymore
|
||||||
|
|
||||||
|
# check that the files are clean and up to date according to cvs
|
||||||
|
my $dirty;
|
||||||
|
foreach my $f (@afiles, @mfiles, @dfiles) {
|
||||||
|
# TODO:we need to handle removed in cvs and/or new (from git)
|
||||||
|
my $status = `cvs -q status "$f" | grep '^File: '`;
|
||||||
|
|
||||||
|
unless ($status =~ m/Status: Up-to-date$/) {
|
||||||
|
$dirty = 1;
|
||||||
|
warn "File $f not up to date in your CVS checkout!\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($dirty) {
|
||||||
|
die "Exiting: your CVS tree is not clean for this merge.";
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
### NOTE: if you are planning to die() past this point
|
||||||
|
### you MUST call cleanupcvs(@files) before die()
|
||||||
|
###
|
||||||
|
|
||||||
|
|
||||||
|
print "'Patching' binary files\n";
|
||||||
|
|
||||||
|
my @bfiles = `git-diff-tree -p $parent $commit | grep '^Binary'`;
|
||||||
|
@bfiles = map { chomp } @bfiles;
|
||||||
|
foreach my $f (@bfiles) {
|
||||||
|
# check that the file in cvs matches the "old" file
|
||||||
|
# extract the file to $tmpdir and comparre with cmp
|
||||||
|
my $tree = `git-rev-parse $parent^{tree} `;
|
||||||
|
chomp $tree;
|
||||||
|
my $blob = `git-ls-tree $tree "$f" | cut -f 1 | cut -d ' ' -f 3`;
|
||||||
|
chomp $blob;
|
||||||
|
`git-cat-file blob $blob > $tmpdir/blob`;
|
||||||
|
`cmp -q $f $tmpdir/blob`;
|
||||||
|
if ($?) {
|
||||||
|
warn "Binary file $f in CVS does not match parent.\n";
|
||||||
|
$dirty = 1;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
# replace with the new file
|
||||||
|
`git-cat-file blob $blob > $f`;
|
||||||
|
|
||||||
|
# TODO: something smart with file modes
|
||||||
|
|
||||||
|
}
|
||||||
|
if ($dirty) {
|
||||||
|
cleanupcvs(@files);
|
||||||
|
die "Exiting: Binary files in CVS do not match parent";
|
||||||
|
}
|
||||||
|
|
||||||
|
## apply non-binary changes
|
||||||
|
my $fuzz = $opt_p ? 0 : 2;
|
||||||
|
|
||||||
|
print "Patching non-binary files\n";
|
||||||
|
print `(git-diff-tree -p $parent -p $commit | patch -p1 -F $fuzz ) 2>&1`;
|
||||||
|
|
||||||
|
my $dirtypatch = 0;
|
||||||
|
if (($? >> 8) == 2) {
|
||||||
|
cleanupcvs(@files);
|
||||||
|
die "Exiting: Patch reported serious trouble -- you will have to apply this patch manually";
|
||||||
|
} elsif (($? >> 8) == 1) { # some hunks failed to apply
|
||||||
|
$dirtypatch = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $f (@afiles) {
|
||||||
|
`cvs add $f`;
|
||||||
|
if ($?) {
|
||||||
|
$dirty = 1;
|
||||||
|
warn "Failed to cvs add $f -- you may need to do it manually";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $f (@dfiles) {
|
||||||
|
`cvs rm -f $f`;
|
||||||
|
if ($?) {
|
||||||
|
$dirty = 1;
|
||||||
|
warn "Failed to cvs rm -f $f -- you may need to do it manually";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print "Commit to CVS\n";
|
||||||
|
my $commitfiles = join(' ', @afiles, @mfiles, @dfiles);
|
||||||
|
my $cmd = "cvs commit -F .msg $commitfiles";
|
||||||
|
|
||||||
|
if ($dirtypatch) {
|
||||||
|
print "NOTE: One or more hunks failed to apply cleanly.\n";
|
||||||
|
print "Resolve the conflicts and then commit using:n";
|
||||||
|
print "\n $cmd\n\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($opt_c) {
|
||||||
|
print "Autocommit\n $cmd\n";
|
||||||
|
print `cvs commit -F .msg $commitfiles 2>&1`;
|
||||||
|
if ($?) {
|
||||||
|
cleanupcvs(@files);
|
||||||
|
die "Exiting: The commit did not succeed";
|
||||||
|
}
|
||||||
|
print "Committed successfully to CVS\n";
|
||||||
|
} else {
|
||||||
|
print "Ready for you to commit, just run:\n\n $cmd\n";
|
||||||
|
}
|
||||||
|
sub usage {
|
||||||
|
print STDERR <<END;
|
||||||
|
Usage: GIT_DIR=/path/to/.gi ${\basename $0} # fetch/update GIT from CVS
|
||||||
|
[-h] [-p] [ parent ] commit
|
||||||
|
END
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
# ensure cvs is clean before we die
|
||||||
|
sub cleanupcvs {
|
||||||
|
my @files = @_;
|
||||||
|
foreach my $f (@files) {
|
||||||
|
`cvs -q update -C "$f"`;
|
||||||
|
if ($?) {
|
||||||
|
warn "Warning! Failed to cleanup state of $f\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -162,10 +162,13 @@ def mergeTrees(head, merge, common, branch1Name, branch2Name):
|
|||||||
# Low level file merging, update and removal
|
# Low level file merging, update and removal
|
||||||
# ------------------------------------------
|
# ------------------------------------------
|
||||||
|
|
||||||
|
MERGE_NONE = 0
|
||||||
|
MERGE_TRIVIAL = 1
|
||||||
|
MERGE_3WAY = 2
|
||||||
def mergeFile(oPath, oSha, oMode, aPath, aSha, aMode, bPath, bSha, bMode,
|
def mergeFile(oPath, oSha, oMode, aPath, aSha, aMode, bPath, bSha, bMode,
|
||||||
branch1Name, branch2Name):
|
branch1Name, branch2Name):
|
||||||
|
|
||||||
merge = False
|
merge = MERGE_NONE
|
||||||
clean = True
|
clean = True
|
||||||
|
|
||||||
if stat.S_IFMT(aMode) != stat.S_IFMT(bMode):
|
if stat.S_IFMT(aMode) != stat.S_IFMT(bMode):
|
||||||
@ -178,7 +181,7 @@ def mergeFile(oPath, oSha, oMode, aPath, aSha, aMode, bPath, bSha, bMode,
|
|||||||
sha = bSha
|
sha = bSha
|
||||||
else:
|
else:
|
||||||
if aSha != oSha and bSha != oSha:
|
if aSha != oSha and bSha != oSha:
|
||||||
merge = True
|
merge = MERGE_TRIVIAL
|
||||||
|
|
||||||
if aMode == oMode:
|
if aMode == oMode:
|
||||||
mode = bMode
|
mode = bMode
|
||||||
@ -208,6 +211,7 @@ def mergeFile(oPath, oSha, oMode, aPath, aSha, aMode, bPath, bSha, bMode,
|
|||||||
os.unlink(src1)
|
os.unlink(src1)
|
||||||
os.unlink(src2)
|
os.unlink(src2)
|
||||||
|
|
||||||
|
merge = MERGE_3WAY
|
||||||
clean = (code == 0)
|
clean = (code == 0)
|
||||||
else:
|
else:
|
||||||
assert(stat.S_ISLNK(aMode) and stat.S_ISLNK(bMode))
|
assert(stat.S_ISLNK(aMode) and stat.S_ISLNK(bMode))
|
||||||
@ -577,14 +581,16 @@ def processRenames(renamesA, renamesB, branchNameA, branchNameB):
|
|||||||
updateFile(False, ren1.dstSha, ren1.dstMode, dstName1)
|
updateFile(False, ren1.dstSha, ren1.dstMode, dstName1)
|
||||||
updateFile(False, ren2.dstSha, ren2.dstMode, dstName2)
|
updateFile(False, ren2.dstSha, ren2.dstMode, dstName2)
|
||||||
else:
|
else:
|
||||||
print 'Renaming', fmtRename(path, ren1.dstName)
|
|
||||||
[resSha, resMode, clean, merge] = \
|
[resSha, resMode, clean, merge] = \
|
||||||
mergeFile(ren1.srcName, ren1.srcSha, ren1.srcMode,
|
mergeFile(ren1.srcName, ren1.srcSha, ren1.srcMode,
|
||||||
ren1.dstName, ren1.dstSha, ren1.dstMode,
|
ren1.dstName, ren1.dstSha, ren1.dstMode,
|
||||||
ren2.dstName, ren2.dstSha, ren2.dstMode,
|
ren2.dstName, ren2.dstSha, ren2.dstMode,
|
||||||
branchName1, branchName2)
|
branchName1, branchName2)
|
||||||
|
|
||||||
if merge:
|
if merge or not clean:
|
||||||
|
print 'Renaming', fmtRename(path, ren1.dstName)
|
||||||
|
|
||||||
|
if merge == MERGE_3WAY:
|
||||||
print 'Auto-merging', ren1.dstName
|
print 'Auto-merging', ren1.dstName
|
||||||
|
|
||||||
if not clean:
|
if not clean:
|
||||||
@ -653,14 +659,16 @@ def processRenames(renamesA, renamesB, branchNameA, branchNameB):
|
|||||||
tryMerge = True
|
tryMerge = True
|
||||||
|
|
||||||
if tryMerge:
|
if tryMerge:
|
||||||
print 'Renaming', fmtRename(ren1.srcName, ren1.dstName)
|
|
||||||
[resSha, resMode, clean, merge] = \
|
[resSha, resMode, clean, merge] = \
|
||||||
mergeFile(ren1.srcName, ren1.srcSha, ren1.srcMode,
|
mergeFile(ren1.srcName, ren1.srcSha, ren1.srcMode,
|
||||||
ren1.dstName, ren1.dstSha, ren1.dstMode,
|
ren1.dstName, ren1.dstSha, ren1.dstMode,
|
||||||
ren1.srcName, srcShaOtherBranch, srcModeOtherBranch,
|
ren1.srcName, srcShaOtherBranch, srcModeOtherBranch,
|
||||||
branchName1, branchName2)
|
branchName1, branchName2)
|
||||||
|
|
||||||
if merge:
|
if merge or not clean:
|
||||||
|
print 'Renaming', fmtRename(ren1.srcName, ren1.dstName)
|
||||||
|
|
||||||
|
if merge == MERGE_3WAY:
|
||||||
print 'Auto-merging', ren1.dstName
|
print 'Auto-merging', ren1.dstName
|
||||||
|
|
||||||
if not clean:
|
if not clean:
|
||||||
|
0
git-pull.sh
Normal file → Executable file
0
git-pull.sh
Normal file → Executable file
@ -92,5 +92,6 @@ if [ "$annotate" ]; then
|
|||||||
object=$(git-mktag < "$GIT_DIR"/TAG_TMP)
|
object=$(git-mktag < "$GIT_DIR"/TAG_TMP)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p "$GIT_DIR/refs/tags"
|
leading=`expr "refs/tags/$name" : '\(.*\)/'` &&
|
||||||
|
mkdir -p "$GIT_DIR/$leading" &&
|
||||||
echo $object > "$GIT_DIR/refs/tags/$name"
|
echo $object > "$GIT_DIR/refs/tags/$name"
|
||||||
|
22
http-push.c
22
http-push.c
@ -28,6 +28,15 @@ static const char http_push_usage[] =
|
|||||||
#define NO_CURL_EASY_DUPHANDLE
|
#define NO_CURL_EASY_DUPHANDLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef XML_STATUS_OK
|
||||||
|
enum XML_Status {
|
||||||
|
XML_STATUS_OK = 1,
|
||||||
|
XML_STATUS_ERROR = 0
|
||||||
|
};
|
||||||
|
#define XML_STATUS_OK 1
|
||||||
|
#define XML_STATUS_ERROR 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define RANGE_HEADER_SIZE 30
|
#define RANGE_HEADER_SIZE 30
|
||||||
|
|
||||||
/* DAV method names and request body templates */
|
/* DAV method names and request body templates */
|
||||||
@ -47,6 +56,7 @@ static int active_requests = 0;
|
|||||||
static int data_received;
|
static int data_received;
|
||||||
static int pushing = 0;
|
static int pushing = 0;
|
||||||
static int aborted = 0;
|
static int aborted = 0;
|
||||||
|
static char remote_dir_exists[256];
|
||||||
|
|
||||||
#ifdef USE_CURL_MULTI
|
#ifdef USE_CURL_MULTI
|
||||||
static int max_requests = -1;
|
static int max_requests = -1;
|
||||||
@ -650,6 +660,7 @@ static void finish_request(struct transfer_request *request)
|
|||||||
if (request->http_code == 404) {
|
if (request->http_code == 404) {
|
||||||
request->state = NEED_PUSH;
|
request->state = NEED_PUSH;
|
||||||
} else if (request->curl_result == CURLE_OK) {
|
} else if (request->curl_result == CURLE_OK) {
|
||||||
|
remote_dir_exists[request->sha1[0]] = 1;
|
||||||
request->state = COMPLETE;
|
request->state = COMPLETE;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "HEAD %s failed, aborting (%d/%ld)\n",
|
fprintf(stderr, "HEAD %s failed, aborting (%d/%ld)\n",
|
||||||
@ -661,6 +672,7 @@ static void finish_request(struct transfer_request *request)
|
|||||||
} else if (request->state == RUN_MKCOL) {
|
} else if (request->state == RUN_MKCOL) {
|
||||||
if (request->curl_result == CURLE_OK ||
|
if (request->curl_result == CURLE_OK ||
|
||||||
request->http_code == 405) {
|
request->http_code == 405) {
|
||||||
|
remote_dir_exists[request->sha1[0]] = 1;
|
||||||
start_put(request);
|
start_put(request);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "MKCOL %s failed, aborting (%d/%ld)\n",
|
fprintf(stderr, "MKCOL %s failed, aborting (%d/%ld)\n",
|
||||||
@ -728,11 +740,12 @@ void process_curl_messages(void)
|
|||||||
slot->curl != curl_message->easy_handle)
|
slot->curl != curl_message->easy_handle)
|
||||||
slot = slot->next;
|
slot = slot->next;
|
||||||
if (slot != NULL) {
|
if (slot != NULL) {
|
||||||
|
int curl_result = curl_message->data.result;
|
||||||
curl_multi_remove_handle(curlm, slot->curl);
|
curl_multi_remove_handle(curlm, slot->curl);
|
||||||
active_requests--;
|
active_requests--;
|
||||||
slot->done = 1;
|
slot->done = 1;
|
||||||
slot->in_use = 0;
|
slot->in_use = 0;
|
||||||
slot->curl_result = curl_message->data.result;
|
slot->curl_result = curl_result;
|
||||||
curl_easy_getinfo(slot->curl,
|
curl_easy_getinfo(slot->curl,
|
||||||
CURLINFO_HTTP_CODE,
|
CURLINFO_HTTP_CODE,
|
||||||
&slot->http_code);
|
&slot->http_code);
|
||||||
@ -767,6 +780,9 @@ void process_request_queue(void)
|
|||||||
start_check(request);
|
start_check(request);
|
||||||
curl_multi_perform(curlm, &num_transfers);
|
curl_multi_perform(curlm, &num_transfers);
|
||||||
} else if (pushing && request->state == NEED_PUSH) {
|
} else if (pushing && request->state == NEED_PUSH) {
|
||||||
|
if (remote_dir_exists[request->sha1[0]])
|
||||||
|
start_put(request);
|
||||||
|
else
|
||||||
start_mkcol(request);
|
start_mkcol(request);
|
||||||
curl_multi_perform(curlm, &num_transfers);
|
curl_multi_perform(curlm, &num_transfers);
|
||||||
}
|
}
|
||||||
@ -1230,7 +1246,7 @@ struct active_lock *lock_remote(char *file, long timeout)
|
|||||||
in_buffer.posn = 0;
|
in_buffer.posn = 0;
|
||||||
in_buffer.buffer = in_data;
|
in_buffer.buffer = in_data;
|
||||||
|
|
||||||
new_lock = xmalloc(sizeof(*new_lock));
|
new_lock = xcalloc(1, sizeof(*new_lock));
|
||||||
new_lock->owner = NULL;
|
new_lock->owner = NULL;
|
||||||
new_lock->token = NULL;
|
new_lock->token = NULL;
|
||||||
new_lock->timeout = -1;
|
new_lock->timeout = -1;
|
||||||
@ -1599,6 +1615,8 @@ int main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(remote_dir_exists, 0, 256);
|
||||||
|
|
||||||
curl_global_init(CURL_GLOBAL_ALL);
|
curl_global_init(CURL_GLOBAL_ALL);
|
||||||
|
|
||||||
#ifdef USE_CURL_MULTI
|
#ifdef USE_CURL_MULTI
|
||||||
|
Loading…
Reference in New Issue
Block a user