Merge branch 'master'

* master:
  Merge branch 'kh/svn'
  git-svnimport: -r adds svn revision number to commit messages
  Merge branch 'jc/commit'
  commit: detect misspelled pathspec while making a partial commit.
  combine-diff: diff-files fix (#2)
  combine-diff: diff-files fix.
  Merge branch 'jc/rebase'
  Merge branch 'ra/email'
maint
Junio C Hamano 2006-02-14 17:56:02 -08:00
commit becb6a658c
6 changed files with 68 additions and 21 deletions

View File

@ -61,6 +61,10 @@ When importing incrementally, you might need to edit the .git/svn2git file.
the git repository. Use this option if you want to import into a the git repository. Use this option if you want to import into a
different branch. different branch.


-r::
Prepend 'rX: ' to commit messages, where X is the imported
subversion revision.

-m:: -m::
Attempt to detect merges based on the commit message. This option Attempt to detect merges based on the commit message. This option
will enable default regexes that try to capture the name source will enable default regexes that try to capture the name source

View File

@ -630,9 +630,10 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
int i, show_hunks, shown_header = 0; int i, show_hunks, shown_header = 0;
char ourtmp_buf[TMPPATHLEN]; char ourtmp_buf[TMPPATHLEN];
char *ourtmp = ourtmp_buf; char *ourtmp = ourtmp_buf;
int working_tree_file = !memcmp(elem->sha1, null_sha1, 20);


/* Read the result of merge first */ /* Read the result of merge first */
if (memcmp(elem->sha1, null_sha1, 20)) { if (!working_tree_file) {
result = grab_blob(elem->sha1, &size); result = grab_blob(elem->sha1, &size);
write_to_temp_file(ourtmp, result, size); write_to_temp_file(ourtmp, result, size);
} }
@ -646,6 +647,7 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
int len = st.st_size; int len = st.st_size;
int cnt = 0; int cnt = 0;


elem->mode = DIFF_FILE_CANON_MODE(st.st_mode);
size = len; size = len;
result = xmalloc(len + 1); result = xmalloc(len + 1);
while (cnt < len) { while (cnt < len) {
@ -661,6 +663,7 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
else { else {
/* deleted file */ /* deleted file */
size = 0; size = 0;
elem->mode = 0;
result = xmalloc(1); result = xmalloc(1);
result[0] = 0; result[0] = 0;
ourtmp = "/dev/null"; ourtmp = "/dev/null";
@ -716,7 +719,7 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent,


show_hunks = make_hunks(sline, cnt, num_parent, dense); show_hunks = make_hunks(sline, cnt, num_parent, dense);


if (show_hunks || mode_differs) { if (show_hunks || mode_differs || working_tree_file) {
const char *abb; const char *abb;


if (header) { if (header) {
@ -731,8 +734,6 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
putchar('\n'); putchar('\n');
printf("index "); printf("index ");
for (i = 0; i < num_parent; i++) { for (i = 0; i < num_parent; i++) {
if (elem->parent[i].mode != elem->mode)
mode_differs = 1;
abb = find_unique_abbrev(elem->parent[i].sha1, abb = find_unique_abbrev(elem->parent[i].sha1,
DEFAULT_ABBREV); DEFAULT_ABBREV);
printf("%s%s", i ? "," : "", abb); printf("%s%s", i ? "," : "", abb);

View File

@ -150,6 +150,8 @@ int main(int argc, const char **argv)
nce->sha1, 20); nce->sha1, 20);
combine.p.parent[stage-2].mode = combine.p.parent[stage-2].mode =
DIFF_FILE_CANON_MODE(mode); DIFF_FILE_CANON_MODE(mode);
combine.p.parent[stage-2].status =
DIFF_STATUS_MODIFIED;
} }


/* diff against the proper unmerged stage */ /* diff against the proper unmerged stage */

View File

@ -180,6 +180,7 @@ verify=t
verbose= verbose=
signoff= signoff=
force_author= force_author=
only_include_assumed=
while case "$#" in 0) break;; esac while case "$#" in 0) break;; esac
do do
case "$1" in case "$1" in
@ -340,12 +341,8 @@ case "$#,$also$only" in
0,) 0,)
;; ;;
*,) *,)
echo >&2 "assuming --only paths..." only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."
also= also=

# If we are going to launch an editor, the message won't be
# shown without this...
test -z "$log_given$status_only" && sleep 1
;; ;;
esac esac
unset only unset only
@ -380,6 +377,8 @@ t,)
;; ;;
,t) ,t)
save_index && save_index &&
git-ls-files --error-unmatch -- "$@" >/dev/null || exit

git-diff-files --name-only -z -- "$@" | git-diff-files --name-only -z -- "$@" |
( (
cd "$TOP" cd "$TOP"
@ -408,7 +407,7 @@ t,)
refuse_partial "Different in index and the last commit: refuse_partial "Different in index and the last commit:
$dirty_in_index" $dirty_in_index"
fi fi
commit_only=`git-ls-files -- "$@"` commit_only=`git-ls-files --error-unmatch -- "$@"` || exit


# Build the temporary index and update the real index # Build the temporary index and update the real index
# the same way. # the same way.
@ -569,7 +568,10 @@ else
PARENTS="" PARENTS=""
fi fi


run_status >>"$GIT_DIR"/COMMIT_EDITMSG {
test -z "$only_include_assumed" || echo "$only_include_assumed"
run_status
} >>"$GIT_DIR"/COMMIT_EDITMSG
if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" ] if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" ]
then then
rm -f "$GIT_DIR/COMMIT_EDITMSG" rm -f "$GIT_DIR/COMMIT_EDITMSG"

View File

@ -30,19 +30,19 @@ die "Need SVN:Core 1.2.1 or better" if $SVN::Core::VERSION lt "1.2.1";
$SIG{'PIPE'}="IGNORE"; $SIG{'PIPE'}="IGNORE";
$ENV{'TZ'}="UTC"; $ENV{'TZ'}="UTC";


our($opt_h,$opt_o,$opt_v,$opt_u,$opt_C,$opt_i,$opt_m,$opt_M,$opt_t,$opt_T,$opt_b,$opt_s,$opt_l,$opt_d,$opt_D); our($opt_h,$opt_o,$opt_v,$opt_u,$opt_C,$opt_i,$opt_m,$opt_M,$opt_t,$opt_T,$opt_b,$opt_r,$opt_s,$opt_l,$opt_d,$opt_D);


sub usage() { sub usage() {
print STDERR <<END; print STDERR <<END;
Usage: ${\basename $0} # fetch/update GIT from SVN Usage: ${\basename $0} # fetch/update GIT from SVN
[-o branch-for-HEAD] [-h] [-v] [-l max_rev] [-o branch-for-HEAD] [-h] [-v] [-l max_rev]
[-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname] [-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname]
[-d|-D] [-i] [-u] [-s start_chg] [-m] [-M regex] [SVN_URL] [-d|-D] [-i] [-u] [-r] [-s start_chg] [-m] [-M regex] [SVN_URL]
END END
exit(1); exit(1);
} }


getopts("b:C:dDhil:mM:o:s:t:T:uv") or usage(); getopts("b:C:dDhil:mM:o:rs:t:T:uv") or usage();
usage if $opt_h; usage if $opt_h;


my $tag_name = $opt_t || "tags"; my $tag_name = $opt_t || "tags";
@ -650,6 +650,7 @@ sub commit {
$pr->reader(); $pr->reader();


$message =~ s/[\s\n]+\z//; $message =~ s/[\s\n]+\z//;
$message = "r$revision: $message" if $opt_r;


print $pw "$message\n" print $pw "$message\n"
or die "Error writing to git-commit-tree: $!\n"; or die "Error writing to git-commit-tree: $!\n";

View File

@ -26,6 +26,8 @@ static int line_terminator = '\n';
static int prefix_len = 0, prefix_offset = 0; static int prefix_len = 0, prefix_offset = 0;
static const char *prefix = NULL; static const char *prefix = NULL;
static const char **pathspec = NULL; static const char **pathspec = NULL;
static int error_unmatch = 0;
static char *ps_matched = NULL;


static const char *tag_cached = ""; static const char *tag_cached = "";
static const char *tag_unmerged = ""; static const char *tag_unmerged = "";
@ -326,7 +328,8 @@ static int cmp_name(const void *p1, const void *p2)
* Match a pathspec against a filename. The first "len" characters * Match a pathspec against a filename. The first "len" characters
* are the common prefix * are the common prefix
*/ */
static int match(const char **spec, const char *filename, int len) static int match(const char **spec, char *ps_matched,
const char *filename, int len)
{ {
const char *m; const char *m;


@ -334,17 +337,24 @@ static int match(const char **spec, const char *filename, int len)
int matchlen = strlen(m + len); int matchlen = strlen(m + len);


if (!matchlen) if (!matchlen)
return 1; goto matched;
if (!strncmp(m + len, filename + len, matchlen)) { if (!strncmp(m + len, filename + len, matchlen)) {
if (m[len + matchlen - 1] == '/') if (m[len + matchlen - 1] == '/')
return 1; goto matched;
switch (filename[len + matchlen]) { switch (filename[len + matchlen]) {
case '/': case '\0': case '/': case '\0':
return 1; goto matched;
} }
} }
if (!fnmatch(m + len, filename + len, 0)) if (!fnmatch(m + len, filename + len, 0))
return 1; goto matched;
if (ps_matched)
ps_matched++;
continue;
matched:
if (ps_matched)
*ps_matched = 1;
return 1;
} }
return 0; return 0;
} }
@ -357,7 +367,7 @@ static void show_dir_entry(const char *tag, struct nond_on_fs *ent)
if (len >= ent->len) if (len >= ent->len)
die("git-ls-files: internal error - directory entry not superset of prefix"); die("git-ls-files: internal error - directory entry not superset of prefix");


if (pathspec && !match(pathspec, ent->name, len)) if (pathspec && !match(pathspec, ps_matched, ent->name, len))
return; return;


fputs(tag, stdout); fputs(tag, stdout);
@ -445,7 +455,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)
if (len >= ce_namelen(ce)) if (len >= ce_namelen(ce))
die("git-ls-files: internal error - cache entry not superset of prefix"); die("git-ls-files: internal error - cache entry not superset of prefix");


if (pathspec && !match(pathspec, ce->name, len)) if (pathspec && !match(pathspec, ps_matched, ce->name, len))
return; return;


if (tag && *tag && show_valid_bit && if (tag && *tag && show_valid_bit &&
@ -719,6 +729,10 @@ int main(int argc, const char **argv)
prefix_offset = 0; prefix_offset = 0;
continue; continue;
} }
if (!strcmp(arg, "--error-unmatch")) {
error_unmatch = 1;
continue;
}
if (*arg == '-') if (*arg == '-')
usage(ls_files_usage); usage(ls_files_usage);
break; break;
@ -730,6 +744,14 @@ int main(int argc, const char **argv)
if (pathspec) if (pathspec)
verify_pathspec(); verify_pathspec();


/* Treat unmatching pathspec elements as errors */
if (pathspec && error_unmatch) {
int num;
for (num = 0; pathspec[num]; num++)
;
ps_matched = xcalloc(1, num);
}

if (show_ignored && !exc_given) { if (show_ignored && !exc_given) {
fprintf(stderr, "%s: --ignored needs some exclude pattern\n", fprintf(stderr, "%s: --ignored needs some exclude pattern\n",
argv[0]); argv[0]);
@ -745,5 +767,20 @@ int main(int argc, const char **argv)
if (prefix) if (prefix)
prune_cache(); prune_cache();
show_files(); show_files();

if (ps_matched) {
/* We need to make sure all pathspec matched otherwise
* it is an error.
*/
int num, errors = 0;
for (num = 0; pathspec[num]; num++) {
if (ps_matched[num])
continue;
error("pathspec '%s' did not match any.",
pathspec[num] + prefix_len);
}
return errors ? 1 : 0;
}

return 0; return 0;
} }