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
commit
becb6a658c
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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";
|
||||||
|
|
51
ls-files.c
51
ls-files.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue