include::diff-generate-patch.txt[]
+
+
+other diff formats
+------------------
+
+The `--summary` option describes newly added, deleted, renamed and
+copied files. The `--stat` option adds diffstat(1) graph to the
+output. These options can be combined with other options, such as
+`-p`, and are meant for human consumption.
+
+When showing a change that involves a rename or a copy, `--stat` output
+formats the pathnames compactly by combining common prefix and suffix of
+the pathnames. For example, a change that moves `arch/i386/Makefile` to
+`arch/x86/Makefile` while modifying 4 lines will be shown like this:
+
+------------------------------------
+arch/{i386 => x86}/Makefile | 4 +--
+------------------------------------
+
+The `--numstat` option gives the diffstat(1) information but is designed
+for easier machine consumption. An entry in `--numstat` output looks
+like this:
+
+----------------------------------------
+1 2 README
+3 1 arch/{i386 => x86}/Makefile
+----------------------------------------
+
+That is, from left to right:
+
+. the number of added lines;
+. a tab;
+. the number of deleted lines;
+. a tab;
+. pathname (possibly with rename/copy information);
+. a newline.
+
+When `-z` output option is in effect, the output is formatted this way:
+
+----------------------------------------
+1 2 README NUL
+3 1 NUL arch/i386/Makefile NUL arch/x86/Makefile NUL
+----------------------------------------
+
+That is:
+
+. the number of added lines;
+. a tab;
+. the number of deleted lines;
+. a tab;
+. a NUL (only exists if renamed/copied);
+. pathname in preimage;
+. a NUL (only exists if renamed/copied);
+. pathname in postimage (only exists if renamed/copied);
+. a NUL.
+
+The extra `NUL` before the preimage path in renamed case is to allow
+scripts that read the output to tell if the current record being read is
+a single-path record or a rename/copy record without reading ahead.
+After reading added and deleted lines, reading up to `NUL` would yield
+the pathname, but if that is `NUL`, the record will show two paths.
Shorthand for "--text".
--ignore-space-at-eol::
- Ignore changes in white spaces at EOL.
+ Ignore changes in whitespace at EOL.
--ignore-space-change::
- Ignore changes in amount of white space. This ignores white
- space at line end, and consider all other sequences of one or
- more white space characters to be equivalent.
+ Ignore changes in amount of whitespace. This ignores whitespace
+ at line end, and considers all other sequences of one or
+ more whitespace characters to be equivalent.
-b::
Shorthand for "--ignore-space-change".
--ignore-all-space::
- Ignore white space when comparing lines. This ignores
- difference even if one line has white space where the other
+ Ignore whitespace when comparing lines. This ignores
+ differences even if one line has whitespace where the other
line has none.
-w::
operation to a subset of the working tree. See ``Interactive
mode'' for details.
--p, \--patch:
+-p, \--patch::
Similar to Interactive mode but the initial command loop is
bypassed and the 'patch' subcommand is invoked using each of
the specified filepatterns before exiting.
--no-add::
When applying a patch, ignore additions made by the
- patch. This can be used to extract common part between
+ patch. This can be used to extract the common part between
two files by first running `diff` on them and applying
the result with this option, which would apply the
deletion part but not addition part.
The unique identifier of an <<def_object,object>>. The <<def_hash,hash>>
of the object's contents using the Secure Hash Algorithm
1 and usually represented by the 40 character hexadecimal encoding of
- the <<def_hash,hash>> of the object (possibly followed by
- a white space).
+ the <<def_hash,hash>> of the object.
[[def_object_type]]object type::
One of the identifiers
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(INSTALL) git$X '$(DESTDIR_SQ)$(bindir_SQ)'
$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
- $(MAKE) -C perl prefix='$(prefix_SQ)' install
+ $(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install
ifndef NO_TCLTK
$(MAKE) -C gitk-git install
$(MAKE) -C git-gui install
}
}
+static void drop_origin_blob(struct origin *o)
+{
+ if (o->file.ptr) {
+ free(o->file.ptr);
+ o->file.ptr = NULL;
+ }
+}
+
/*
* Each group of lines is described by a blame_entry; it can be split
* as we pass blame to the parents. They form a linked list in the
}
}
diff_flush(&diff_opts);
+ diff_tree_release_paths(&diff_opts);
if (porigin) {
/*
* Create a freestanding copy that is not part of
}
}
diff_flush(&diff_opts);
+ diff_tree_release_paths(&diff_opts);
return porigin;
}
}
}
diff_flush(&diff_opts);
-
+ diff_tree_release_paths(&diff_opts);
return retval;
}
}
finish:
- for (i = 0; i < MAXPARENT; i++)
- origin_decref(parent_origin[i]);
+ for (i = 0; i < MAXPARENT; i++) {
+ if (parent_origin[i]) {
+ drop_origin_blob(parent_origin[i]);
+ origin_decref(parent_origin[i]);
+ }
+ }
+ drop_origin_blob(origin);
}
/*
rev.verbose_header = 1;
rev.show_root_diff = 1;
rev.commit_format = get_commit_format("format:%h: %s");
- rev.always_show_header = 1;
+ rev.always_show_header = 0;
printf("Created %scommit ", initial_commit ? "initial " : "");
- log_tree_commit(&rev, commit);
- printf("\n");
+ if (!log_tree_commit(&rev, commit)) {
+ struct strbuf buf = STRBUF_INIT;
+ format_commit_message(commit, "%h: %s", &buf);
+ printf("%s\n", buf.buf);
+ strbuf_release(&buf);
+ }
}
int git_commit_config(const char *k, const char *v)
mark_object(object);
printf("blob\nmark :%d\ndata %lu\n", last_idnum, size);
- if (fwrite(buf, size, 1, stdout) != 1)
+ if (size && fwrite(buf, size, 1, stdout) != 1)
die ("Could not write blob %s", sha1_to_hex(sha1));
printf("\n");
list++;
sub_size--;
}
+ if (!sub_size) {
+ /*
+ * It is possible for some "paths" to have
+ * so many objects that no hash boundary
+ * might be found. Let's just steal the
+ * exact half in that case.
+ */
+ sub_size = victim->remaining / 2;
+ list -= sub_size;
+ }
target->list = list;
victim->list_size -= sub_size;
victim->remaining -= sub_size;
return 1;
diffcore_std(&opt);
diff_flush(&opt);
+ diff_tree_release_paths(&opt);
if (!index_was_discarded)
/* The index is still clobbered from do_diff_cache() */
"# Write a tag message\n"
"#\n";
+static void set_signingkey(const char *value)
+{
+ if (strlcpy(signingkey, value, sizeof(signingkey)) >= sizeof(signingkey))
+ die("signing key value too long (%.10s...)", value);
+}
+
static int git_tag_config(const char *var, const char *value)
{
if (!strcmp(var, "user.signingkey")) {
if (!value)
die("user.signingkey without value");
- if (strlcpy(signingkey, value, sizeof(signingkey))
- >= sizeof(signingkey))
- die("user.signingkey value too long");
+ set_signingkey(value);
return 0;
}
argc = parse_options(argc, argv, options, git_tag_usage, 0);
+ if (keyid) {
+ sign = 1;
+ set_signingkey(keyid);
+ }
if (sign)
annotate = 1;
/* pager.c */
extern void setup_pager(void);
extern char *pager_program;
-extern int pager_in_use;
+extern int pager_in_use(void);
extern int pager_use_color;
extern char *editor_program;
auto_color:
if (stdout_is_tty < 0)
stdout_is_tty = isatty(1);
- if (stdout_is_tty || (pager_in_use && pager_use_color)) {
+ if (stdout_is_tty || (pager_in_use() && pager_use_color)) {
char *term = getenv("TERM");
if (term && strcmp(term, "dumb"))
return 1;
export exec_prefix mandir
export srcdir VPATH
+ASCIIDOC8=@ASCIIDOC8@
NEEDS_SSL_WITH_CRYPTO=@NEEDS_SSL_WITH_CRYPTO@
NO_OPENSSL=@NO_OPENSSL@
NO_CURL=@NO_CURL@
AC_SUBST(TCLTK_PATH)
fi
fi
+AC_CHECK_PROGS(ASCIIDOC, [asciidoc])
+if test -n "$ASCIIDOC"; then
+ AC_MSG_CHECKING([for asciidoc version])
+ asciidoc_version=`$ASCIIDOC --version 2>&1`
+ case "${asciidoc_version}" in
+ asciidoc' '8*)
+ ASCIIDOC8=YesPlease
+ AC_MSG_RESULT([${asciidoc_version} > 7])
+ ;;
+ asciidoc' '7*)
+ ASCIIDOC8=
+ AC_MSG_RESULT([${asciidoc_version}])
+ ;;
+ *)
+ ASCIIDOC8=
+ AC_MSG_RESULT([${asciidoc_version} (unknown)])
+ ;;
+ esac
+fi
+AC_SUBST(ASCIIDOC8)
+
## Checks for libraries.
AC_MSG_NOTICE([CHECKS for libraries])
(eval-when-compile (require 'cl))
(require 'ewoc)
(require 'log-edit)
+(require 'easymenu)
;;;; Customizations
(define-key toggle-map "i" 'git-toggle-show-ignored)
(define-key toggle-map "k" 'git-toggle-show-unknown)
(define-key toggle-map "m" 'git-toggle-all-marks)
- (setq git-status-mode-map map)))
+ (setq git-status-mode-map map))
+ (easy-menu-define git-menu git-status-mode-map
+ "Git Menu"
+ `("Git"
+ ["Refresh" git-refresh-status t]
+ ["Commit" git-commit-file t]
+ ("Merge"
+ ["Next Unmerged File" git-next-unmerged-file t]
+ ["Prev Unmerged File" git-prev-unmerged-file t]
+ ["Mark as Resolved" git-resolve-file t]
+ ["Interactive Merge File" git-find-file-imerge t]
+ ["Diff Against Common Base File" git-diff-file-base t]
+ ["Diff Combined" git-diff-file-combined t]
+ ["Diff Against Merge Head" git-diff-file-merge-head t]
+ ["Diff Against Mine" git-diff-file-mine t]
+ ["Diff Against Other" git-diff-file-other t])
+ "--------"
+ ["Add File" git-add-file t]
+ ["Revert File" git-revert-file t]
+ ["Ignore File" git-ignore-file t]
+ ["Remove File" git-remove-file t]
+ "--------"
+ ["Find File" git-find-file t]
+ ["View File" git-view-file t]
+ ["Diff File" git-diff-file t]
+ ["Interactive Diff File" git-diff-file-idiff t]
+ ["Log" git-log-file t]
+ "--------"
+ ["Mark" git-mark-file t]
+ ["Mark All" git-mark-all t]
+ ["Unmark" git-unmark-file t]
+ ["Unmark All" git-unmark-all t]
+ ["Toggle All Marks" git-toggle-all-marks t]
+ ["Hide Handled Files" git-remove-handled t]
+ "--------"
+ ["Show Uptodate Files" git-toggle-show-uptodate :style toggle :selected git-show-uptodate]
+ ["Show Ignored Files" git-toggle-show-ignored :style toggle :selected git-show-ignored]
+ ["Show Unknown Files" git-toggle-show-unknown :style toggle :selected git-show-unknown]
+ "--------"
+ ["Quit" git-status-quit t])))
+
;; git mode should only run in the *git status* buffer
(put 'git-status-mode 'mode-class 'special)
int nr;
int alloc;
struct diffstat_file {
+ char *from_name;
char *name;
+ char *print_name;
unsigned is_unmerged:1;
unsigned is_binary:1;
unsigned is_renamed:1;
}
diffstat->files[diffstat->nr++] = x;
if (name_b) {
- x->name = pprint_rename(name_a, name_b);
+ x->from_name = xstrdup(name_a);
+ x->name = xstrdup(name_b);
x->is_renamed = 1;
}
- else
+ else {
+ x->from_name = NULL;
x->name = xstrdup(name_a);
+ }
return x;
}
printf("%s", reset);
}
+static void fill_print_name(struct diffstat_file *file)
+{
+ char *pname;
+
+ if (file->print_name)
+ return;
+
+ if (!file->is_renamed) {
+ struct strbuf buf;
+ strbuf_init(&buf, 0);
+ if (quote_c_style(file->name, &buf, NULL, 0)) {
+ pname = strbuf_detach(&buf, NULL);
+ } else {
+ pname = file->name;
+ strbuf_release(&buf);
+ }
+ } else {
+ pname = pprint_rename(file->from_name, file->name);
+ }
+ file->print_name = pname;
+}
+
static void show_stats(struct diffstat_t* data, struct diff_options *options)
{
int i, len, add, del, total, adds = 0, dels = 0;
for (i = 0; i < data->nr; i++) {
struct diffstat_file *file = data->files[i];
int change = file->added + file->deleted;
-
- if (!file->is_renamed) { /* renames are already quoted by pprint_rename */
- struct strbuf buf;
- strbuf_init(&buf, 0);
- if (quote_c_style(file->name, &buf, NULL, 0)) {
- free(file->name);
- file->name = strbuf_detach(&buf, NULL);
- } else {
- strbuf_release(&buf);
- }
- }
-
- len = strlen(file->name);
+ fill_print_name(file);
+ len = strlen(file->print_name);
if (max_len < len)
max_len = len;
for (i = 0; i < data->nr; i++) {
const char *prefix = "";
- char *name = data->files[i]->name;
+ char *name = data->files[i]->print_name;
int added = data->files[i]->added;
int deleted = data->files[i]->deleted;
int name_len;
printf("%s%d%s", add_c, added, reset);
printf(" bytes");
printf("\n");
- goto free_diffstat_file;
+ continue;
}
else if (data->files[i]->is_unmerged) {
show_name(prefix, name, len, reset, set);
printf(" Unmerged\n");
- goto free_diffstat_file;
+ continue;
}
else if (!data->files[i]->is_renamed &&
(added + deleted == 0)) {
total_files--;
- goto free_diffstat_file;
+ continue;
}
/*
show_graph('+', add, add_c, reset);
show_graph('-', del, del_c, reset);
putchar('\n');
- free_diffstat_file:
- free(data->files[i]->name);
- free(data->files[i]);
}
- free(data->files);
printf("%s %d files changed, %d insertions(+), %d deletions(-)%s\n",
set, total_files, adds, dels, reset);
}
dels += deleted;
}
}
- free(data->files[i]->name);
- free(data->files[i]);
}
- free(data->files);
-
printf(" %d files changed, %d insertions(+), %d deletions(-)\n",
total_files, adds, dels);
}
{
int i;
+ if (data->nr == 0)
+ return;
+
for (i = 0; i < data->nr; i++) {
struct diffstat_file *file = data->files[i];
printf("-\t-\t");
else
printf("%d\t%d\t", file->added, file->deleted);
- if (!file->is_renamed) {
- write_name_quoted(file->name, stdout, options->line_termination);
+ if (options->line_termination) {
+ fill_print_name(file);
+ if (!file->is_renamed)
+ write_name_quoted(file->name, stdout,
+ options->line_termination);
+ else {
+ fputs(file->print_name, stdout);
+ putchar(options->line_termination);
+ }
} else {
- fputs(file->name, stdout);
- putchar(options->line_termination);
+ if (file->is_renamed) {
+ putchar('\0');
+ write_name_quoted(file->from_name, stdout, '\0');
+ }
+ write_name_quoted(file->name, stdout, '\0');
}
}
}
+static void free_diffstat_info(struct diffstat_t *diffstat)
+{
+ int i;
+ for (i = 0; i < diffstat->nr; i++) {
+ struct diffstat_file *f = diffstat->files[i];
+ if (f->name != f->print_name)
+ free(f->print_name);
+ free(f->name);
+ free(f->from_name);
+ free(f);
+ }
+ free(diffstat->files);
+}
+
struct checkdiff_t {
struct xdiff_emit_state xm;
const char *filename;
int i, spaces = 0, space_before_tab = 0, white_space_at_end = 0;
/* check space before tab */
- for (i = 1; i < len && (line[i] == ' ' || line[i] == '\t'); i++)
+ for (i = 1; i < len; i++) {
if (line[i] == ' ')
spaces++;
- if (line[i - 1] == '\t' && spaces)
- space_before_tab = 1;
+ else if (line[i] == '\t') {
+ if (spaces) {
+ space_before_tab = 1;
+ break;
+ }
+ }
+ else
+ break;
+ }
- /* check white space at line end */
+ /* check whitespace at line end */
if (line[len - 1] == '\n')
len--;
if (isspace(line[len - 1]))
putchar(',');
}
if (white_space_at_end)
- printf("white space at end");
+ printf("whitespace at end");
printf(":%s ", reset);
emit_line_with_ws(1, set, reset, ws, line, len,
data->ws_rule);
show_numstat(&diffstat, options);
if (output_format & DIFF_FORMAT_DIFFSTAT)
show_stats(&diffstat, options);
- else if (output_format & DIFF_FORMAT_SHORTSTAT)
+ if (output_format & DIFF_FORMAT_SHORTSTAT)
show_shortstats(&diffstat);
+ free_diffstat_info(&diffstat);
separator++;
}
size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT;
size_t delta_base_cache_limit = 16 * 1024 * 1024;
char *pager_program;
-int pager_in_use;
int pager_use_color = 1;
char *editor_program;
char *excludes_file;
OPTIONS_KEEPDASHDASH=t
OPTIONS_SPEC="\
-git-branch [options] [<branch>] [<paths>...]
+git-checkout [options] [<branch>] [<paths>...]
--
b= create a new branch started at <branch>
-l create the new branchs reflog
-track tells if the new branch should track the remote branch
+l create the new branch's reflog
+track arrange that the new branch tracks the remote branch
f proceed even if the index or working tree is not HEAD
-m performa three-way merge on local modifications if needed
+m merge local modifications into the new branch
q,quiet be quiet
"
SUBDIRECTORY_OK=Sometimes
# it is local
if base=$(get_repo_base "$repo"); then
repo="$base"
- local=yes
+ if test -z "$depth"
+ then
+ local=yes
+ fi
fi
dir="$2"
find objects -type f -print | sed -e 1q)
# objects directory should not be empty because
# we are cloning!
- test -f "$repo/$sample_file" || exit
+ test -f "$repo/$sample_file" ||
+ die "fatal: cannot clone empty repository"
if ln "$repo/$sample_file" "$GIT_DIR/objects/sample" 2>/dev/null
then
rm -f "$GIT_DIR/objects/sample"
echo "ERROR: $4: Not merging symbolic link changes."
exit 1
;;
+ *,160000,*)
+ echo "ERROR: $4: Not merging conflicting submodule changes."
+ exit 1
+ ;;
esac
src2=`git-unpack-file $3`
$initial_reply_to = $_;
}
-
-$initial_reply_to =~ s/^\s*<?/</;
-$initial_reply_to =~ s/>?\s*$/>/;
+if (defined $initial_reply_to && $_ ne "") {
+ $initial_reply_to =~ s/^\s*<?/</;
+ $initial_reply_to =~ s/>?\s*$/>/;
+}
if (!defined $smtp_server) {
foreach (qw( /usr/sbin/sendmail /usr/lib/sendmail )) {
}
sub log_use_color {
- return 1 if $color;
- my ($dc, $dcvar);
- $dcvar = 'color.diff';
- $dc = `git-config --get $dcvar`;
- if ($dc eq '') {
- # nothing at all; fallback to "diff.color"
- $dcvar = 'diff.color';
- $dc = `git-config --get $dcvar`;
- }
- chomp($dc);
- if ($dc eq 'auto') {
- my $pc;
- $pc = `git-config --get color.pager`;
- if ($pc eq '') {
- # does not have it -- fallback to pager.color
- $pc = `git-config --bool --get pager.color`;
- }
- else {
- $pc = `git-config --bool --get color.pager`;
- if ($?) {
- $pc = 'false';
- }
- }
- chomp($pc);
- if (-t *STDOUT || (defined $pager && $pc eq 'true')) {
- return ($ENV{TERM} && $ENV{TERM} ne 'dumb');
- }
- return 0;
- }
- return 0 if $dc eq 'never';
- return 1 if $dc eq 'always';
- chomp($dc = `git-config --bool --get $dcvar`);
- return ($dc eq 'true');
+ return $color || Git->repository->get_colorbool('color.diff');
}
sub git_svn_log_cmd {
} elsif (length $pager == 0 || $pager eq 'cat') {
$pager = undef;
}
+ $ENV{GIT_PAGER_IN_USE} = defined($pager);
}
sub run_pager {
char *ep;
char timeout_header[25];
struct remote_lock *lock = NULL;
- XML_Parser parser = XML_ParserCreate(NULL);
- enum XML_Status result;
struct curl_slist *dav_headers = NULL;
struct xml_ctx ctx;
if (start_active_slot(slot)) {
run_active_slot(slot);
if (results.curl_result == CURLE_OK) {
+ XML_Parser parser = XML_ParserCreate(NULL);
+ enum XML_Status result;
ctx.name = xcalloc(10, 1);
ctx.len = 0;
ctx.cdata = NULL;
XML_GetErrorCode(parser)));
lock->timeout = -1;
}
+ XML_ParserFree(parser);
}
} else {
fprintf(stderr, "Unable to start LOCK request\n");
struct buffer out_buffer;
char *in_data;
char *out_data;
- XML_Parser parser = XML_ParserCreate(NULL);
- enum XML_Status result;
struct curl_slist *dav_headers = NULL;
struct xml_ctx ctx;
struct remote_ls_ctx ls;
if (start_active_slot(slot)) {
run_active_slot(slot);
if (results.curl_result == CURLE_OK) {
+ XML_Parser parser = XML_ParserCreate(NULL);
+ enum XML_Status result;
ctx.name = xcalloc(10, 1);
ctx.len = 0;
ctx.cdata = NULL;
XML_ErrorString(
XML_GetErrorCode(parser)));
}
+ XML_ParserFree(parser);
}
} else {
fprintf(stderr, "Unable to start PROPFIND request\n");
struct buffer out_buffer;
char *in_data;
char *out_data;
- XML_Parser parser = XML_ParserCreate(NULL);
- enum XML_Status result;
struct curl_slist *dav_headers = NULL;
struct xml_ctx ctx;
int lock_flags = 0;
if (start_active_slot(slot)) {
run_active_slot(slot);
if (results.curl_result == CURLE_OK) {
+ XML_Parser parser = XML_ParserCreate(NULL);
+ enum XML_Status result;
ctx.name = xcalloc(10, 1);
ctx.len = 0;
ctx.cdata = NULL;
XML_GetErrorCode(parser)));
lock_flags = 0;
}
+ XML_ParserFree(parser);
}
} else {
fprintf(stderr, "Unable to start PROPFIND request\n");
free(result_buf.ptr);
result.clean = (merge_status == 0);
- } else {
- if (!(S_ISLNK(a->mode) || S_ISLNK(b->mode)))
- die("cannot merge modes?");
-
+ } else if (S_ISGITLINK(a->mode)) {
+ result.clean = 0;
+ hashcpy(result.sha, a->sha1);
+ } else if (S_ISLNK(a->mode)) {
hashcpy(result.sha, a->sha1);
if (!sha_eq(a->sha1, b->sha1))
result.clean = 0;
+ } else {
+ die("unsupported object type in the tree");
}
}
* something different on Windows, for example.
*/
+static int spawned_pager;
+
static void run_pager(const char *pager)
{
/*
else if (!*pager || !strcmp(pager, "cat"))
return;
- pager_in_use = 1; /* means we are emitting to terminal */
+ spawned_pager = 1; /* means we are emitting to terminal */
if (pipe(fd) < 0)
return;
die("unable to execute pager '%s'", pager);
exit(255);
}
+
+int pager_in_use(void)
+{
+ const char *env;
+
+ if (spawned_pager)
+ return 1;
+
+ env = getenv("GIT_PAGER_IN_USE");
+ return env ? git_config_bool("GIT_PAGER_IN_USE", env) : 0;
+}
$pm{'private-Error.pm'} = '$(INST_LIBDIR)/Error.pm';
}
-my %extra;
-$extra{DESTDIR} = $ENV{DESTDIR} if $ENV{DESTDIR};
-
# redirect stdout, otherwise the message "Writing perl.mak for Git"
# disrupts the output for the target 'instlibdir'
open STDOUT, ">&STDERR";
VERSION_FROM => 'Git.pm',
PM => \%pm,
MAKEFILE => 'perl.mak',
- INSTALLSITEMAN3DIR => '$(SITEPREFIX)/share/man/man3',
- %extra
+ INSTALLSITEMAN3DIR => '$(SITEPREFIX)/share/man/man3'
);
git diff -b > out
test_expect_success 'another test, with -b' 'git diff expect out'
+
+test_expect_success 'check mixed spaces and tabs in indent' '
+
+ # This is indented with SP HT SP.
+ echo " foo();" > x &&
+ git diff --check | grep "space before tab"
+
+'
+
test_done
git diff expect actual
'
+get_tag_header u-signed-tag $commit commit $time >expect
+echo 'Another message' >>expect
+echo '-----BEGIN PGP SIGNATURE-----' >>expect
+test_expect_success 'sign with a given key id' '
+
+ git tag -u committer@example.com -m "Another message" u-signed-tag &&
+ get_tag_msg u-signed-tag >actual &&
+ git diff expect actual
+
+'
+
+test_expect_success 'sign with an unknown id (1)' '
+
+ ! git tag -u author@example.com -m "Another message" o-signed-tag
+
+'
+
+test_expect_success 'sign with an unknown id (2)' '
+
+ ! git tag -u DEADBEEF -m "Another message" o-signed-tag
+
+'
+
+cat >fakeeditor <<'EOF'
+#!/bin/sh
+test -n "$1" && exec >"$1"
+echo A signed tag message
+echo from a fake editor.
+EOF
+chmod +x fakeeditor
+
+get_tag_header implied-sign $commit commit $time >expect
+./fakeeditor >>expect
+echo '-----BEGIN PGP SIGNATURE-----' >>expect
+test_expect_success '-u implies signed tag' '
+ GIT_EDITOR=./fakeeditor git-tag -u CDDE430D implied-sign &&
+ get_tag_msg implied-sign >actual &&
+ git diff expect actual
+'
+
cat >sigmsgfile <<EOF
Another signed tag
message in a file.
git diff expect actual
'
-cat >fakeeditor <<'EOF'
-#!/bin/sh
-test -n "$1" && exec >"$1"
-echo A signed tag message
-echo from a fake editor.
-EOF
-chmod +x fakeeditor
get_tag_header implied-annotate $commit commit $time >expect
./fakeeditor >>expect
echo '-----BEGIN PGP SIGNATURE-----' >>expect
. ./test-lib.sh
+test_tick
+
fill () {
for i
do
test_expect_success setup '
+ fill x y z > same &&
fill 1 2 3 4 5 6 7 8 >one &&
fill a b c d e >two &&
- git add one two &&
+ git add same one two &&
git commit -m "Initial A one, A two" &&
git checkout -b renamer &&
'
+test_expect_success "checkout with unrelated dirty tree without -m" '
+
+ git checkout -f master &&
+ fill 0 1 2 3 4 5 6 7 8 >same &&
+ cp same kept
+ git checkout side >messages &&
+ git diff same kept
+ (cat > messages.expect <<EOF
+M same
+EOF
+) &&
+ touch messages.expect &&
+ git diff messages.expect messages
+'
+
test_expect_success "checkout -m with dirty tree" '
git checkout -f master &&
git clean -f &&
fill 0 1 2 3 4 5 6 7 8 >one &&
- git checkout -m side &&
+ git checkout -m side > messages &&
test "$(git symbolic-ref HEAD)" = "refs/heads/side" &&
+ (cat >expect.messages <<EOF
+Merging side with local
+Merging:
+ab76817 Side M one, D two, A three
+virtual local
+found 1 common ancestor(s):
+7329388 Initial A one, A two
+Auto-merged one
+M one
+EOF
+) &&
+ git diff expect.messages messages &&
+
fill "M one" "A three" "D two" >expect.master &&
git diff --name-status master >current.master &&
diff expect.master current.master &&
test_expect_success 'checkout to detach HEAD' '
git checkout -f renamer && git clean -f &&
- git checkout renamer^ &&
+ git checkout renamer^ 2>messages &&
+ (cat >messages.expect <<EOF
+Note: moving to "renamer^" which isn'"'"'t a local branch
+If you want to create a new branch from this checkout, you may do so
+(now or later) by using -b with the checkout command again. Example:
+ git checkout -b <new_branch_name>
+HEAD is now at 7329388... Initial A one, A two
+EOF
+) &&
+ git diff messages.expect messages &&
H=$(git rev-parse --verify HEAD) &&
M=$(git show-ref -s --verify refs/heads/master) &&
test "z$H" = "z$M" &&
test_description='git-svn info'
. ./lib-git-svn.sh
+say 'skipping svn-info test (has a race undiagnosed yet)'
+test_done
ptouch() {
perl -w -e '
die("unable to set up diff options to follow renames");
diff_tree(t1, t2, base, &diff_opts);
diffcore_std(&diff_opts);
+ diff_tree_release_paths(&diff_opts);
/* Go through the new set of filepairing, and see if we find a more interesting one */
for (i = 0; i < q->nr; i++) {
choice = p;
/* Update the path we use from now on.. */
+ diff_tree_release_paths(opt);
opt->paths[0] = xstrdup(p->one->path);
diff_tree_setup_paths(opt->paths, opt);
break;