mirror of
https://github.com/git/git.git
synced 2026-03-14 02:43:25 +01:00
Merge branch 'ew/rerere' into next
* ew/rerere: rerere: record (or avoid misrecording) resolved, skipped or aborted rebase/am git-rerere: add 'gc' command. rerere: add clear, diff, and status commands Documentation: simpler shared repository creation shortlog: fix segfault on empty authorname Add branch.*.merge warning and documentation update Fix perl/ build. git-svn: use do_switch for --follow-parent if the SVN library supports it Fix documentation copy&paste typo git-svn: extra error check to ensure we open a file correctly
This commit is contained in:
@@ -125,10 +125,17 @@ apply.whitespace::
|
||||
|
||||
branch.<name>.remote::
|
||||
When in branch <name>, it tells `git fetch` which remote to fetch.
|
||||
If this option is not given, `git fetch` defaults to remote "origin".
|
||||
|
||||
branch.<name>.merge::
|
||||
When in branch <name>, it tells `git fetch` the default remote branch
|
||||
to be merged.
|
||||
When in branch <name>, it tells `git fetch` the default refspec to
|
||||
be marked for merging in FETCH_HEAD. The value has exactly to match
|
||||
a remote part of one of the refspecs which are fetched from the remote
|
||||
given by "branch.<name>.remote".
|
||||
The merge information is used by `git pull` (which at first calls
|
||||
`git fetch`) to lookup the default branch for merging. Without
|
||||
this option, `git pull` defaults to merge the first refspec fetched.
|
||||
Specify multiple values to get an octopus merge.
|
||||
|
||||
pager.color::
|
||||
A boolean to enable/disable colored output when the pager is in
|
||||
|
||||
@@ -43,8 +43,8 @@ Pull: refs/heads/master:refs/remotes/origin/master
|
||||
------------
|
||||
================================
|
||||
|
||||
You can update the shared repository with your changes by first commiting
|
||||
your changes, and then using:
|
||||
You can update the shared repository with your changes by first committing
|
||||
your changes, and then using the gitlink:git-push[1] command:
|
||||
|
||||
------------------------------------------------
|
||||
$ git push origin master
|
||||
@@ -76,11 +76,15 @@ possibly created from scratch or from a tarball (see the
|
||||
link:tutorial.html[tutorial]), or imported from an already existing CVS
|
||||
repository (see the next section).
|
||||
|
||||
If your project's working directory is /home/alice/myproject, you can
|
||||
create a shared repository at /pub/repo.git with:
|
||||
Assume your existing repo is at /home/alice/myproject. Create a new "bare"
|
||||
repository (a repository without a working tree) and fetch your project into
|
||||
it:
|
||||
|
||||
------------------------------------------------
|
||||
$ git clone -bare /home/alice/myproject /pub/repo.git
|
||||
$ mkdir /pub/my-repo.git
|
||||
$ cd /pub/my-repo.git
|
||||
$ git --bare init-db --shared
|
||||
$ git --bare fetch /home/alice/myproject master:master
|
||||
------------------------------------------------
|
||||
|
||||
Next, give every team member read/write access to this repository. One
|
||||
@@ -93,10 +97,7 @@ Put all the committers in the same group, and make the repository
|
||||
writable by that group:
|
||||
|
||||
------------------------------------------------
|
||||
$ cd /pub
|
||||
$ chgrp -R $group repo.git
|
||||
$ find repo.git -mindepth 1 -type d |xargs chmod ug+rwx,g+s
|
||||
$ GIT_DIR=repo.git git repo-config core.sharedrepository true
|
||||
$ chgrp -R $group /pub/my-repo.git
|
||||
------------------------------------------------
|
||||
|
||||
Make sure committers have a umask of at most 027, so that the directories
|
||||
@@ -107,15 +108,15 @@ Importing a CVS archive
|
||||
|
||||
First, install version 2.1 or higher of cvsps from
|
||||
link:http://www.cobite.com/cvsps/[http://www.cobite.com/cvsps/] and make
|
||||
sure it is in your path. The magic command line is then
|
||||
sure it is in your path. Then cd to a checked out CVS working directory
|
||||
of the project you are interested in and run gitlink:git-cvsimport[1]:
|
||||
|
||||
-------------------------------------------
|
||||
$ git cvsimport -v -d <cvsroot> -C <destination> <module>
|
||||
$ git cvsimport -C <destination>
|
||||
-------------------------------------------
|
||||
|
||||
This puts a git archive of the named CVS module in the directory
|
||||
<destination>, which will be created if necessary. The -v option makes
|
||||
the conversion script very chatty.
|
||||
<destination>, which will be created if necessary.
|
||||
|
||||
The import checks out from CVS every revision of every file. Reportedly
|
||||
cvsimport can average some twenty revisions per second, so for a
|
||||
|
||||
@@ -7,8 +7,7 @@ git-rerere - Reuse recorded resolve
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-rerere'
|
||||
|
||||
'git-rerere' [clear|diff|status]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@@ -27,6 +26,38 @@ results and applying the previously recorded hand resolution.
|
||||
You need to create `$GIT_DIR/rr-cache` directory to enable this
|
||||
command.
|
||||
|
||||
|
||||
COMMANDS
|
||||
--------
|
||||
|
||||
Normally, git-rerere is run without arguments or user-intervention.
|
||||
However, it has several commands that allow it to interact with
|
||||
its working state.
|
||||
|
||||
'clear'::
|
||||
|
||||
This resets the metadata used by rerere if a merge resolution is to be
|
||||
is aborted. Calling gitlink:git-am[1] --skip or gitlink:git-rebase[1]
|
||||
[--skip|--abort] will automatcally invoke this command.
|
||||
|
||||
'diff'::
|
||||
|
||||
This displays diffs for the current state of the resolution. It is
|
||||
useful for tracking what has changed while the user is resolving
|
||||
conflicts. Additional arguments are passed directly to the system
|
||||
diff(1) command installed in PATH.
|
||||
|
||||
'status'::
|
||||
|
||||
Like diff, but this only prints the filenames that will be tracked
|
||||
for resolutions.
|
||||
|
||||
'gc'::
|
||||
|
||||
This command is used to prune records of conflicted merge that
|
||||
occurred long time ago.
|
||||
|
||||
|
||||
DISCUSSION
|
||||
----------
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ static void read_from_stdin(struct path_list *list)
|
||||
bob = buffer + strlen(buffer);
|
||||
else {
|
||||
offset = 8;
|
||||
while (isspace(bob[-1]))
|
||||
if (isspace(bob[-1]))
|
||||
bob--;
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ static void get_from_rev(struct rev_info *rev, struct path_list *list)
|
||||
author = scratch;
|
||||
authorlen = strlen(scratch);
|
||||
} else {
|
||||
while (bracket[-1] == ' ')
|
||||
if (bracket[-1] == ' ')
|
||||
bracket--;
|
||||
|
||||
author = buffer + 7;
|
||||
|
||||
@@ -246,6 +246,10 @@ last=`cat "$dotest/last"`
|
||||
this=`cat "$dotest/next"`
|
||||
if test "$skip" = t
|
||||
then
|
||||
if test -d "$GIT_DIR/rr-cache"
|
||||
then
|
||||
git-rerere clear
|
||||
fi
|
||||
this=`expr "$this" + 1`
|
||||
resume=
|
||||
fi
|
||||
@@ -408,6 +412,10 @@ do
|
||||
stop_here_user_resolve $this
|
||||
fi
|
||||
apply_status=0
|
||||
if test -d "$GIT_DIR/rr-cache"
|
||||
then
|
||||
git rerere
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@@ -134,6 +134,8 @@ canon_refs_list_for_fetch () {
|
||||
# or the first one otherwise; add prefix . to the rest
|
||||
# to prevent the secondary branches to be merged by default.
|
||||
merge_branches=
|
||||
found_mergeref=
|
||||
curr_branch=
|
||||
if test "$1" = "-d"
|
||||
then
|
||||
shift ; remote="$1" ; shift
|
||||
@@ -171,6 +173,10 @@ canon_refs_list_for_fetch () {
|
||||
dot_prefix= && break
|
||||
done
|
||||
fi
|
||||
if test -z $dot_prefix
|
||||
then
|
||||
found_mergeref=true
|
||||
fi
|
||||
case "$remote" in
|
||||
'') remote=HEAD ;;
|
||||
refs/heads/* | refs/tags/* | refs/remotes/*) ;;
|
||||
@@ -191,6 +197,11 @@ canon_refs_list_for_fetch () {
|
||||
fi
|
||||
echo "${dot_prefix}${force}${remote}:${local}"
|
||||
done
|
||||
if test -z "$found_mergeref" -a "$curr_branch"
|
||||
then
|
||||
echo >&2 "Warning: No merge candidate found because value of config option
|
||||
\"branch.${curr_branch}.merge\" does not match any remote branch fetched."
|
||||
fi
|
||||
}
|
||||
|
||||
# Returns list of src: (no store), or src:dst (store)
|
||||
|
||||
@@ -139,6 +139,10 @@ do
|
||||
--skip)
|
||||
if test -d "$dotest"
|
||||
then
|
||||
if test -d "$GIT_DIR/rr-cache"
|
||||
then
|
||||
git-rerere clear
|
||||
fi
|
||||
prev_head="`cat $dotest/prev_head`"
|
||||
end="`cat $dotest/end`"
|
||||
msgnum="`cat $dotest/msgnum`"
|
||||
@@ -157,6 +161,10 @@ do
|
||||
exit
|
||||
;;
|
||||
--abort)
|
||||
if test -d "$GIT_DIR/rr-cache"
|
||||
then
|
||||
git-rerere clear
|
||||
fi
|
||||
if test -d "$dotest"
|
||||
then
|
||||
rm -r "$dotest"
|
||||
|
||||
@@ -169,9 +169,66 @@ sub merge {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub garbage_collect_rerere {
|
||||
# We should allow specifying these from the command line and
|
||||
# that is why the caller gives @ARGV to us, but I am lazy.
|
||||
|
||||
my $cutoff_noresolve = 15; # two weeks
|
||||
my $cutoff_resolve = 60; # two months
|
||||
my @to_remove;
|
||||
while (<$rr_dir/*/preimage>) {
|
||||
my ($dir) = /^(.*)\/preimage$/;
|
||||
my $cutoff = ((-f "$dir/postimage")
|
||||
? $cutoff_resolve
|
||||
: $cutoff_noresolve);
|
||||
my $age = -M "$_";
|
||||
if ($cutoff <= $age) {
|
||||
push @to_remove, $dir;
|
||||
}
|
||||
}
|
||||
if (@to_remove) {
|
||||
rmtree(\@to_remove);
|
||||
}
|
||||
}
|
||||
|
||||
-d "$rr_dir" || exit(0);
|
||||
|
||||
read_rr();
|
||||
|
||||
if (@ARGV) {
|
||||
my $arg = shift @ARGV;
|
||||
if ($arg eq 'clear') {
|
||||
for my $path (keys %merge_rr) {
|
||||
my $name = $merge_rr{$path};
|
||||
if (-d "$rr_dir/$name" &&
|
||||
! -f "$rr_dir/$name/postimage") {
|
||||
rmtree(["$rr_dir/$name"]);
|
||||
}
|
||||
}
|
||||
unlink $merge_rr;
|
||||
}
|
||||
elsif ($arg eq 'status') {
|
||||
for my $path (keys %merge_rr) {
|
||||
print $path, "\n";
|
||||
}
|
||||
}
|
||||
elsif ($arg eq 'diff') {
|
||||
for my $path (keys %merge_rr) {
|
||||
my $name = $merge_rr{$path};
|
||||
system('diff', ((@ARGV == 0) ? ('-u') : @ARGV),
|
||||
'-L', "a/$path", '-L', "b/$path",
|
||||
"$rr_dir/$name/preimage", $path);
|
||||
}
|
||||
}
|
||||
elsif ($arg eq 'gc') {
|
||||
garbage_collect_rerere(@ARGV);
|
||||
}
|
||||
else {
|
||||
die "$0 unknown command: $arg\n";
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my %conflict = map { $_ => 1 } find_conflict();
|
||||
|
||||
# MERGE_RR records paths with conflicts immediately after merge
|
||||
|
||||
49
git-svn.perl
49
git-svn.perl
@@ -72,7 +72,7 @@ my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,
|
||||
$_username, $_config_dir, $_no_auth_cache, $_xfer_delta,
|
||||
$_pager, $_color);
|
||||
my (@_branch_from, %tree_map, %users, %rusers, %equiv);
|
||||
my ($_svn_co_url_revs, $_svn_pg_peg_revs);
|
||||
my ($_svn_co_url_revs, $_svn_pg_peg_revs, $_svn_can_do_switch);
|
||||
my @repo_path_split_cache;
|
||||
|
||||
my %fc_opts = ( 'no-ignore-externals' => \$_no_ignore_ext,
|
||||
@@ -2877,6 +2877,24 @@ sub libsvn_connect {
|
||||
return $ra;
|
||||
}
|
||||
|
||||
sub libsvn_can_do_switch {
|
||||
unless (defined $_svn_can_do_switch) {
|
||||
my $pool = SVN::Pool->new;
|
||||
my $rep = eval {
|
||||
$SVN->do_switch(1, '', 0, $SVN->{url},
|
||||
SVN::Delta::Editor->new, $pool);
|
||||
};
|
||||
if ($@) {
|
||||
$_svn_can_do_switch = 0;
|
||||
} else {
|
||||
$rep->abort_report($pool);
|
||||
$_svn_can_do_switch = 1;
|
||||
}
|
||||
$pool->clear;
|
||||
}
|
||||
$_svn_can_do_switch;
|
||||
}
|
||||
|
||||
sub libsvn_dup_ra {
|
||||
my ($ra) = @_;
|
||||
SVN::Ra->new(map { $_ => $ra->{$_} } qw/config url
|
||||
@@ -3198,12 +3216,26 @@ sub libsvn_find_parent_branch {
|
||||
unlink $GIT_SVN_INDEX;
|
||||
print STDERR "Found branch parent: ($GIT_SVN) $parent\n";
|
||||
sys(qw/git-read-tree/, $parent);
|
||||
# I can't seem to get do_switch() to work correctly with
|
||||
# the SWIG interface (TypeError when passing switch_url...),
|
||||
# so we'll unconditionally bypass the delta interface here
|
||||
# for now
|
||||
return libsvn_fetch_full($parent, $paths, $rev,
|
||||
$author, $date, $msg);
|
||||
unless (libsvn_can_do_switch()) {
|
||||
return libsvn_fetch_full($parent, $paths, $rev,
|
||||
$author, $date, $msg);
|
||||
}
|
||||
# do_switch works with svn/trunk >= r22312, but that is not
|
||||
# included with SVN 1.4.2 (the latest version at the moment),
|
||||
# so we can't rely on it.
|
||||
my $ra = libsvn_connect("$url/$branch_from");
|
||||
my $ed = SVN::Git::Fetcher->new({c => $parent, q => $_q});
|
||||
my $pool = SVN::Pool->new;
|
||||
my $reporter = $ra->do_switch($rev, '', 1, $SVN->{url},
|
||||
$ed, $pool);
|
||||
my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef) : ();
|
||||
$reporter->set_path('', $r0, 0, @lock, $pool);
|
||||
$reporter->finish_report($pool);
|
||||
$pool->clear;
|
||||
unless ($ed->{git_commit_ok}) {
|
||||
die "SVN connection failed somewhere...\n";
|
||||
}
|
||||
return libsvn_log_entry($rev, $author, $date, $msg, [$parent]);
|
||||
}
|
||||
print STDERR "Nope, branch point not imported or unknown\n";
|
||||
return undef;
|
||||
@@ -3438,6 +3470,9 @@ sub open_file {
|
||||
my ($self, $path, $pb, $rev) = @_;
|
||||
my ($mode, $blob) = (safe_qx('git-ls-tree',$self->{c},'--',$path)
|
||||
=~ /^(\d{6}) blob ([a-f\d]{40})\t/);
|
||||
unless (defined $mode && defined $blob) {
|
||||
die "$path was not found in commit $self->{c} (r$rev)\n";
|
||||
}
|
||||
{ path => $path, mode_a => $mode, mode_b => $mode, blob => $blob,
|
||||
pool => SVN::Pool->new, action => 'M' };
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ our %feature = (
|
||||
# To disable system wide have in $GITWEB_CONFIG
|
||||
# $feature{'snapshot'}{'default'} = [undef];
|
||||
# To have project specific config enable override in $GITWEB_CONFIG
|
||||
# $feature{'blame'}{'override'} = 1;
|
||||
# $feature{'snapshot'}{'override'} = 1;
|
||||
# and in project config gitweb.snapshot = none|gzip|bzip2;
|
||||
'snapshot' => {
|
||||
'sub' => \&feature_snapshot,
|
||||
|
||||
@@ -29,7 +29,7 @@ $(makfile): ../GIT-CFLAGS Makefile
|
||||
echo ' echo $(instdir_SQ)' >> $@
|
||||
else
|
||||
$(makfile): Makefile.PL ../GIT-CFLAGS
|
||||
'$(PERL_PATH_SQ)' $< FIRST_MAKEFILE='$@' PREFIX='$(prefix_SQ)'
|
||||
'$(PERL_PATH_SQ)' $< PREFIX='$(prefix_SQ)'
|
||||
endif
|
||||
|
||||
# this is just added comfort for calling make directly in perl dir
|
||||
|
||||
@@ -24,5 +24,6 @@ WriteMakefile(
|
||||
NAME => 'Git',
|
||||
VERSION_FROM => 'Git.pm',
|
||||
PM => \%pm,
|
||||
MAKEFILE => 'perl.mak',
|
||||
%extra
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user