Merge branch 'sb/merge-friendly' into next

* sb/merge-friendly:
  Display 'theirs' branch name when possible in merge.
  Use extended SHA1 syntax in merge-recursive conflicts.
  gitweb: Allow search to be disabled from the config file.
  gitweb: Require a minimum of two character for the search text.
  gitweb: Use rev-list pattern search options.
  checkout: make the message about the need for a new branch a bit clearer
  gitweb: optimize git_summary.
  gitweb: optimize git_shortlog_body.
  gitweb: optimize git_get_last_activity.
  gitweb: Add missing show '...' links change.
  Make git-show-branch options similar to git-branch.
  Keep "git --git-dir" from causing a bus error.
  git-svn: enable common fetch/commit options for dcommit
  vc-git: Ignore errors caused by a non-existent directory in vc-git-registered.
  Remove NO_ACCURATE_DIFF options from build systems
  git-tag: lose exit after die
  Really fix headers for __FreeBSD__
  Do not support "partial URL shorthand" anymore.
  default pull: forget about "newbie protection" for now.
  merge and reset: adjust for "reset --hard" messages
This commit is contained in:
Junio C Hamano
2006-12-23 01:30:04 -08:00
16 changed files with 113 additions and 93 deletions

View File

@@ -8,7 +8,7 @@ git-show-branch - Show branches and their commits
SYNOPSIS
--------
[verse]
'git-show-branch' [--all] [--heads] [--tags] [--topo-order] [--current]
'git-show-branch' [--all] [--remotes] [--topo-order] [--current]
[--more=<n> | --list | --independent | --merge-base]
[--no-name | --sha1-name] [--topics] [<rev> | <glob>]...
@@ -37,9 +37,11 @@ OPTIONS
branches under $GIT_DIR/refs/heads/topic, giving
`topic/*` would show all of them.
--all --heads --tags::
Show all refs under $GIT_DIR/refs, $GIT_DIR/refs/heads,
and $GIT_DIR/refs/tags, respectively.
-r|--remotes::
Show the remote-tracking branches.
-a|--all::
Show both remote-tracking branches and local branches.
--current::
With this option, the command includes the current

View File

@@ -79,9 +79,6 @@ all:
#
# Define NO_ICONV if your libc does not properly support iconv.
#
# Define NO_ACCURATE_DIFF if your diff program at least sometimes misses
# a missing newline at the end of the file.
#
# Define USE_NSEC below if you want git to care about sub-second file mtimes
# and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and
# it will BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely
@@ -551,9 +548,6 @@ else
endif
endif
endif
ifdef NO_ACCURATE_DIFF
BASIC_CFLAGS += -DNO_ACCURATE_DIFF
endif
ifdef NO_PERL_MAKEMAKER
export NO_PERL_MAKEMAKER
endif

View File

@@ -4,7 +4,7 @@
#include "builtin.h"
static const char show_branch_usage[] =
"git-show-branch [--sparse] [--current] [--all] [--heads] [--tags] [--topo-order] [--more=count | --list | --independent | --merge-base ] [--topics] [<refs>...] | --reflog[=n] <branch>";
"git-show-branch [--sparse] [--current] [--all] [--remotes] [--topo-order] [--more=count | --list | --independent | --merge-base ] [--topics] [<refs>...] | --reflog[=n] <branch>";
static int default_num;
static int default_alloc;
@@ -383,6 +383,20 @@ static int append_head_ref(const char *refname, const unsigned char *sha1, int f
return append_ref(refname + ofs, sha1, flag, cb_data);
}
static int append_remote_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
unsigned char tmp[20];
int ofs = 13;
if (strncmp(refname, "refs/remotes/", ofs))
return 0;
/* If both heads/foo and tags/foo exists, get_sha1 would
* get confused.
*/
if (get_sha1(refname + ofs, tmp) || hashcmp(tmp, sha1))
ofs = 5;
return append_ref(refname + ofs, sha1, flag, cb_data);
}
static int append_tag_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
if (strncmp(refname, "refs/tags/", 10))
@@ -423,16 +437,16 @@ static int append_matching_ref(const char *refname, const unsigned char *sha1, i
return append_ref(refname, sha1, flag, cb_data);
}
static void snarf_refs(int head, int tag)
static void snarf_refs(int head, int remotes)
{
if (head) {
int orig_cnt = ref_name_cnt;
for_each_ref(append_head_ref, NULL);
sort_ref_range(orig_cnt, ref_name_cnt);
}
if (tag) {
if (remotes) {
int orig_cnt = ref_name_cnt;
for_each_ref(append_tag_ref, NULL);
for_each_ref(append_remote_ref, NULL);
sort_ref_range(orig_cnt, ref_name_cnt);
}
}
@@ -554,7 +568,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
struct commit_list *list = NULL, *seen = NULL;
unsigned int rev_mask[MAX_REVS];
int num_rev, i, extra = 0;
int all_heads = 0, all_tags = 0;
int all_heads = 0, all_remotes = 0;
int all_mask, all_revs;
int lifo = 1;
char head[128];
@@ -586,12 +600,10 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
ac--; av++;
break;
}
else if (!strcmp(arg, "--all"))
all_heads = all_tags = 1;
else if (!strcmp(arg, "--heads"))
all_heads = 1;
else if (!strcmp(arg, "--tags"))
all_tags = 1;
else if (!strcmp(arg, "--all") || !strcmp(arg, "-a"))
all_heads = all_remotes = 1;
else if (!strcmp(arg, "--remotes") || !strcmp(arg, "-r"))
all_remotes = 1;
else if (!strcmp(arg, "--more"))
extra = 1;
else if (!strcmp(arg, "--list"))
@@ -636,11 +648,11 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
usage(show_branch_usage);
/* If nothing is specified, show all branches by default */
if (ac + all_heads + all_tags == 0)
if (ac + all_heads + all_remotes == 0)
all_heads = 1;
if (all_heads + all_tags)
snarf_refs(all_heads, all_tags);
if (all_heads + all_remotes)
snarf_refs(all_heads, all_remotes);
if (reflog) {
int reflen;
if (!ac)

View File

@@ -235,9 +235,6 @@ AC_SUBST(NO_SETENV)
#
# Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
# Enable it on Windows. By default, symrefs are still used.
#
# Define NO_ACCURATE_DIFF if your diff program at least sometimes misses
# a missing newline at the end of the file.
## Site configuration (override autodetection)
## --with-PACKAGE[=ARG] and --without-PACKAGE

View File

@@ -58,8 +58,9 @@
(with-temp-buffer
(let* ((dir (file-name-directory file))
(name (file-relative-name file dir)))
(when dir (cd dir))
(and (ignore-errors (eq 0 (call-process "git" nil '(t nil) nil "ls-files" "-c" "-z" "--" name)))
(and (ignore-errors
(when dir (cd dir))
(eq 0 (call-process "git" nil '(t nil) nil "ls-files" "-c" "-z" "--" name)))
(let ((str (buffer-string)))
(and (> (length str) (length name))
(string= (substring str 0 (1+ (length name))) (concat name "\0"))))))))

View File

@@ -146,8 +146,11 @@ fi
[ -z "$branch$newbranch" ] &&
[ "$new" != "$old" ] &&
die "git checkout: to checkout the requested commit you need to specify
a name for a new branch which is created and switched to"
die "git checkout: provided reference cannot be checked out directly
You need -b to associate a new branch with the wanted checkout. Example:
git checkout -b <new_branch_name> $arg
"
if [ "X$old" = X ]
then

View File

@@ -11,7 +11,7 @@
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#if !defined(__APPLE__) && !defined(__FreeBSD)
#if !defined(__APPLE__) && !defined(__FreeBSD__)
#define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */
#define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
#endif

View File

@@ -32,7 +32,7 @@ savestate() {
restorestate() {
if test -f "$GIT_DIR/MERGE_SAVE"
then
git reset --hard $head
git reset --hard $head >/dev/null
cpio -iuv <"$GIT_DIR/MERGE_SAVE"
git-update-index --refresh >/dev/null
fi
@@ -266,6 +266,8 @@ do
remotehead=$(git-rev-parse --verify "$remote"^0 2>/dev/null) ||
die "$remote - not something we can merge"
remoteheads="${remoteheads}$remotehead "
eval GITHEAD_$remotehead='"$remote"'
export GITHEAD_$remotehead
done
set x $remoteheads ; shift

View File

@@ -7,18 +7,7 @@ GIT_DIR=$(git-rev-parse --git-dir 2>/dev/null) || :;
get_data_source () {
case "$1" in
*/*)
# Not so fast. This could be the partial URL shorthand...
token=$(expr "z$1" : 'z\([^/]*\)/')
remainder=$(expr "z$1" : 'z[^/]*/\(.*\)')
if test "$(git-repo-config --get "remote.$token.url")"
then
echo config-partial
elif test -f "$GIT_DIR/branches/$token"
then
echo branches-partial
else
echo ''
fi
echo ''
;;
*)
if test "$(git-repo-config --get "remote.$1.url")"
@@ -40,12 +29,7 @@ get_remote_url () {
data_source=$(get_data_source "$1")
case "$data_source" in
'')
echo "$1" ;;
config-partial)
token=$(expr "z$1" : 'z\([^/]*\)/')
remainder=$(expr "z$1" : 'z[^/]*/\(.*\)')
url=$(git-repo-config --get "remote.$token.url")
echo "$url/$remainder"
echo "$1"
;;
config)
git-repo-config --get "remote.$1.url"
@@ -54,14 +38,10 @@ get_remote_url () {
sed -ne '/^URL: */{
s///p
q
}' "$GIT_DIR/remotes/$1" ;;
}' "$GIT_DIR/remotes/$1"
;;
branches)
sed -e 's/#.*//' "$GIT_DIR/branches/$1" ;;
branches-partial)
token=$(expr "z$1" : 'z\([^/]*\)/')
remainder=$(expr "z$1" : 'z[^/]*/\(.*\)')
url=$(sed -e 's/#.*//' "$GIT_DIR/branches/$token")
echo "$url/$remainder"
sed -e 's/#.*//' "$GIT_DIR/branches/$1"
;;
*)
die "internal error: get-remote-url $1" ;;
@@ -77,7 +57,7 @@ get_default_remote () {
get_remote_default_refs_for_push () {
data_source=$(get_data_source "$1")
case "$data_source" in
'' | config-partial | branches | branches-partial)
'' | branches)
;; # no default push mapping, just send matching refs.
config)
git-repo-config --get-all "remote.$1.push" ;;
@@ -145,13 +125,6 @@ canon_refs_list_for_fetch () {
merge_branches=$(git-repo-config \
--get-all "branch.${curr_branch}.merge")
fi
# If we are fetching only one branch, then first branch
# is the only thing that makes sense to merge anyway,
# so there is no point refusing that traditional rule.
if test $# != 1 && test "z$merge_branches" = z
then
merge_branches=..this..would..never..match..
fi
fi
for ref
do
@@ -203,7 +176,7 @@ canon_refs_list_for_fetch () {
get_remote_default_refs_for_fetch () {
data_source=$(get_data_source "$1")
case "$data_source" in
'' | config-partial | branches-partial)
'')
echo "HEAD:" ;;
config)
canon_refs_list_for_fetch -d "$1" \

View File

@@ -292,6 +292,7 @@ then
fi
# Rewind the head to "$onto"; this saves our current head in ORIG_HEAD.
echo "First, rewinding head to replay your work on top of it..."
git-reset --hard "$onto"
# If the $onto is a proper descendant of the tip of the branch, then

View File

@@ -111,7 +111,7 @@ my %cmd = (
{ 'merge|m|M' => \$_merge,
'strategy|s=s' => \$_strategy,
'dry-run|n' => \$_dry_run,
%cmt_opts } ],
%cmt_opts, %fc_opts } ],
'set-tree' => [ \&commit, "Set an SVN repository to a git tree-ish",
{ 'stdin|' => \$_stdin, %cmt_opts, %fc_opts, } ],
'show-ignore' => [ \&show_ignore, "Show svn:ignore listings",

View File

@@ -40,7 +40,6 @@ do
message="$1"
if test "$#" = "0"; then
die "error: option -m needs an argument"
exit 2
else
message_given=1
fi
@@ -50,7 +49,6 @@ do
shift
if test "$#" = "0"; then
die "error: option -F needs an argument"
exit 2
else
message="$(cat "$1")"
message_given=1

6
git.c
View File

@@ -59,8 +59,10 @@ static int handle_options(const char*** argv, int* argc)
} else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) {
setup_pager();
} else if (!strcmp(cmd, "--git-dir")) {
if (*argc < 1)
return -1;
if (*argc < 2) {
fprintf(stderr, "No directory given for --git-dir.\n" );
usage(git_usage_string);
}
setenv("GIT_DIR", (*argv)[1], 1);
(*argv)++;
(*argc)--;

View File

@@ -128,6 +128,12 @@ our %feature = (
# => [content-encoding, suffix, program]
'default' => ['x-gzip', 'gz', 'gzip']},
# Enable text search, which will list the commits which match author,
# committer or commit text to a given string. Enabled by default.
'search' => {
'override' => 0,
'default' => [1]},
# Enable the pickaxe search, which will list the commits that modified
# a given string in a file. This can be practical and quite faster
# alternative to 'blame', but still potentially CPU-intensive.
@@ -351,6 +357,9 @@ if (defined $searchtext) {
if ($searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) {
die_error(undef, "Invalid search parameter");
}
if (length($searchtext) < 2) {
die_error(undef, "At least two characters are required for search parameter");
}
$searchtext = quotemeta $searchtext;
}
@@ -1139,8 +1148,9 @@ sub git_get_last_activity {
$git_dir = "$projectroot/$path";
open($fd, "-|", git_cmd(), 'for-each-ref',
'--format=%(refname) %(committer)',
'--format=%(committer)',
'--sort=-committerdate',
'--count=1',
'refs/heads') or return;
my $most_recent = <$fd>;
close $fd or return;
@@ -1726,6 +1736,9 @@ EOF
print " / $action";
}
print "\n";
}
my ($have_search) = gitweb_check_feature('search');
if ((defined $project) && ($have_search)) {
if (!defined $searchtext) {
$searchtext = "";
}
@@ -2635,6 +2648,8 @@ sub git_shortlog_body {
# uses global variable $project
my ($revlist, $from, $to, $refs, $extra) = @_;
my $have_snapshot = gitweb_have_snapshot();
$from = 0 unless defined $from;
$to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
@@ -2662,7 +2677,7 @@ sub git_shortlog_body {
$cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") . " | " .
$cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff") . " | " .
$cgi->a({-href => href(action=>"tree", hash=>$commit, hash_base=>$commit)}, "tree");
if (gitweb_have_snapshot()) {
if ($have_snapshot) {
print " | " . $cgi->a({-href => href(action=>"snapshot", hash=>$commit)}, "snapshot");
}
print "</td>\n" .
@@ -2908,9 +2923,9 @@ sub git_project_index {
sub git_summary {
my $descr = git_get_project_description($project) || "none";
my $head = git_get_head_hash($project);
my %co = parse_commit($head);
my %co = parse_commit("HEAD");
my %cd = parse_date($co{'committer_epoch'}, $co{'committer_tz'});
my $head = $co{'id'};
my $owner = git_get_project_owner($project);
@@ -2957,7 +2972,7 @@ sub git_summary {
# we need to request one more than 16 (0..15) to check if
# those 16 are all
open my $fd, "-|", git_cmd(), "rev-list", "--max-count=17",
git_get_head_hash($project), "--"
$head, "--"
or die_error(undef, "Open git-rev-list failed");
my @revlist = map { chomp; $_ } <$fd>;
close $fd;
@@ -2983,6 +2998,7 @@ sub git_summary {
if (@forklist) {
git_print_header_div('forks');
git_project_list_body(\@forklist, undef, 0, 15,
$#forklist <= 15 ? undef :
$cgi->a({-href => href(action=>"forks")}, "..."),
'noheader');
}
@@ -4144,6 +4160,10 @@ sub git_history {
}
sub git_search {
my ($have_search) = gitweb_check_feature('search');
if (!$have_search) {
die_error('403 Permission denied', "Permission denied");
}
if (!defined $searchtext) {
die_error(undef, "Text field empty");
}
@@ -4172,20 +4192,20 @@ sub git_search {
print "<table cellspacing=\"0\">\n";
my $alternate = 1;
if ($searchtype eq 'commit' or $searchtype eq 'author' or $searchtype eq 'committer') {
my $greptype;
if ($searchtype eq 'commit') {
$greptype = "--grep=";
} elsif ($searchtype eq 'author') {
$greptype = "--author=";
} elsif ($searchtype eq 'committer') {
$greptype = "--committer=";
}
$/ = "\0";
open my $fd, "-|", git_cmd(), "rev-list",
"--header", "--parents", $hash, "--"
"--header", "--parents", ($greptype . $searchtext),
$hash, "--"
or next;
while (my $commit_text = <$fd>) {
if (!grep m/$searchtext/i, $commit_text) {
next;
}
if ($searchtype eq 'author' && !grep m/\nauthor .*$searchtext/i, $commit_text) {
next;
}
if ($searchtype eq 'committer' && !grep m/\ncommitter .*$searchtext/i, $commit_text) {
next;
}
my @commit_lines = split "\n", $commit_text;
my %co = parse_commit(undef, \@commit_lines);
if (!%co) {

View File

@@ -649,8 +649,8 @@ static struct merge_file_info merge_file(struct diff_filespec *o,
char *name1, *name2;
int merge_status;
name1 = xstrdup(mkpath("%s/%s", branch1, a->path));
name2 = xstrdup(mkpath("%s/%s", branch2, b->path));
name1 = xstrdup(mkpath("%s:%s", branch1, a->path));
name2 = xstrdup(mkpath("%s:%s", branch2, b->path));
fill_mm(o->sha1, &orig);
fill_mm(a->sha1, &src1);
@@ -1263,6 +1263,18 @@ static struct commit *get_ref(const char *ref)
return (struct commit *)object;
}
static const char *better_branch_name(const char *branch)
{
static char githead_env[8 + 40 + 1];
char *name;
if (strlen(branch) != 40)
return branch;
sprintf(githead_env, "GITHEAD_%s", branch);
name = getenv(githead_env);
return name ? name : branch;
}
int main(int argc, char *argv[])
{
static const char *bases[2];
@@ -1293,11 +1305,14 @@ int main(int argc, char *argv[])
branch1 = argv[++i];
branch2 = argv[++i];
printf("Merging %s with %s\n", branch1, branch2);
h1 = get_ref(branch1);
h2 = get_ref(branch2);
branch1 = better_branch_name(branch1);
branch2 = better_branch_name(branch2);
printf("Merging %s with %s\n", branch1, branch2);
if (bases_count == 1) {
struct commit *ancestor = get_ref(bases[0]);
clean = merge(h1, h2, branch1, branch2, 0, ancestor, &result);

View File

@@ -59,18 +59,18 @@ GIT_AUTHOR_DATE="2006-12-12 23:00:08" git commit -m F
test_expect_failure "combined merge conflicts" "git merge -m final G"
cat > expect << EOF
<<<<<<< HEAD/a1
<<<<<<< HEAD:a1
F
=======
G
>>>>>>> 26f86b677eb03d4d956dbe108b29cb77061c1e73/a1
>>>>>>> G:a1
EOF
test_expect_success "result contains a conflict" "diff -u expect a1"
git ls-files --stage > out
cat > expect << EOF
100644 f16f906ab60483c100d1241dfc39868de9ec9fcb 1 a1
100644 da056ce14a2241509897fa68bb2b3b6e6194ef9e 1 a1
100644 cf84443e49e1b366fac938711ddf4be2d4d1d9e9 2 a1
100644 fd7923529855d0b274795ae3349c5e0438333979 3 a1
EOF