Browse Source

Sync with 1.7.11.6

Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Junio C Hamano 13 years ago
parent
commit
1c88a6d174
  1. 88
      Documentation/RelNotes/1.7.11.6.txt
  2. 4
      Documentation/asciidoc.conf
  3. 12
      Documentation/git-config.txt
  4. 9
      Documentation/git-submodule.txt
  5. 3
      Documentation/git.txt
  6. 2
      Documentation/user-manual.conf
  7. 1
      builtin/apply.c
  8. 9
      builtin/blame.c
  9. 3
      builtin/checkout.c
  10. 8
      builtin/config.c
  11. 3
      builtin/diff.c
  12. 3
      builtin/merge.c
  13. 1
      cache.h
  14. 3
      diff-no-index.c
  15. 5
      diff.c
  16. 2
      diff.h
  17. 123
      git-mergetool.sh
  18. 1
      git-stash.sh
  19. 35
      git-submodule.sh
  20. 22
      merge-recursive.c
  21. 6
      notes-merge.c
  22. 3
      patch-ids.c
  23. 6
      read-cache.c
  24. 3
      revision.c
  25. 2
      run-command.c
  26. 3
      submodule.c
  27. 18
      t/t3401-rebase-partial.sh
  28. 30
      t/t4022-diff-rewrite.sh
  29. 26
      t/t7400-submodule-basic.sh
  30. 28
      t/t7406-submodule-update.sh
  31. 38
      t/t7610-mergetool.sh
  32. 3
      tree-diff.c

88
Documentation/RelNotes/1.7.11.6.txt

@ -4,59 +4,81 @@ Git v1.7.11.6 Release Notes @@ -4,59 +4,81 @@ Git v1.7.11.6 Release Notes
Fixes since v1.7.11.5
---------------------

This consists primarily of documentation updates and low-impact code
clarification and bugfixes.

- "ciabot" script (in contrib/) has been updated with extensive
* "ciabot" script (in contrib/) has been updated with extensive
documentation.

- The "--rebase" option to "git pull" can be abbreviated to "-r",
but we didn't document it.
* "git foo" errored out with "Not a directory" when the user had a
non-directory on $PATH, and worse yet it masked an alias "foo" from
running.

- It was generally understood that "--long-option"s to many of our
subcommands can be abbreviated to the unique prefix, but it was not
easy to find it described for new readers of the documentation set.
* When the user exports a non-default IFS without HT, scripts that
rely on being able to parse "ls-files -s | while read a b c..."
started to fail. Protect them from such a misconfiguration.

- The "--topo-order", "--date-order" (and the lack of either means
the default order) options to "rev-list" and "log" family of
commands were poorly described in the documentation.
* When the user gives an argument that can be taken as both a
revision name and a pathname without disambiguating with "--", we
used to give a help message "Use '--' to separate". The message
has been clarified to show where that '--' goes on the command
line.

* Documentation for the configuration file format had a confusing
example.

- Older parts of the documentation described as if having a regular
* Older parts of the documentation described as if having a regular
file in .git/refs/ hierarchy were the only way to have branches and
tags, which is not true for quite some time.

- A utility shell function test_seq has been added as a replacement
for the 'seq' utility found on some platforms.
* It was generally understood that "--long-option"s to many of our
subcommands can be abbreviated to the unique prefix, but it was not
easy to find it described for new readers of the documentation set.

- Fallback 'getpass' implementation made unportable use of stdio API.
* The "--topo-order", "--date-order" (and the lack of either means
the default order) options to "rev-list" and "log" family of
commands were poorly described in the documentation.

- "git commit --amend" let the user edit the log message and then
* "git commit --amend" let the user edit the log message and then
died when the human-readable committer name was given
insufficiently by getpwent(3).

- The reflog entries left by "git rebase" and "git rebase -i" were
inconsistent (the interactive one gave an abbreviated object name).
* The exit status code from "git config" was way overspecified while
being incorrect. The implementation has been updated to give the
documented status for a case that was documented, and introduce a
new code for "all other errors".

- When the user exports a non-default IFS without HT, scripts that
rely on being able to parse "ls-files -s | while read a b c..."
started to fail. Protect them from such a misconfiguration.
* The output from "git diff -B" for a file that ends with an
incomplete line did not put "\ No newline..." on a line of its own.

* "git diff" had a confusion between taking data from a path in the
working tree and taking data from an object that happens to have
name 0{40} recorded in a tree.

- When "git push" triggered the automatic gc on the receiving end, a
* The "--rebase" option to "git pull" can be abbreviated to "-r",
but we didn't document it.

* When "git push" triggered the automatic gc on the receiving end, a
message from "git prune" that said it was removing cruft leaked to
the standard output, breaking the communication protocol.

- "git diff" had a confusion between taking data from a path in the
working tree and taking data from an object that happens to have
name 0{40} recorded in a tree.
* The reflog entries left by "git rebase" and "git rebase -i" were
inconsistent (the interactive one gave an abbreviated object name).

- "git send-email" did not unquote encoded words that appear on the
* "git send-email" did not unquote encoded words that appear on the
header correctly, and lost "_" from strings.

- When the user gives an argument that can be taken as both a
revision name and a pathname without disambiguating with "--", we
used to give a help message "Use '--' to separate". The message
has been clarified to show where that '--' goes on the command
line.
* "git stash apply/pop" did not trigger "rerere" upon conflicts
unlike other mergy operations.

* "git submodule <cmd> path" did not error out when the path to the
submodule was misspelt.

- "gitweb" when used with PATH_INFO failed to notice directories with
* "git submodule update -f" did not update paths in the working tree
that has local changes.
(merge 01d4721 sz/submodule-force-update later to maint).

* "gitweb" when used with PATH_INFO failed to notice directories with
SP (and other characters that need URL-style quoting) in them.

* Fallback 'getpass' implementation made unportable use of stdio API.

* A utility shell function test_seq has been added as a replacement
for the 'seq' utility found on some platforms.

4
Documentation/asciidoc.conf

@ -36,7 +36,7 @@ ifndef::git-asciidoc-no-roff[] @@ -36,7 +36,7 @@ ifndef::git-asciidoc-no-roff[]
# v1.72 breaks with this because it replaces dots not in roff requests.
[listingblock]
<example><title>{title}</title>
<literallayout>
<literallayout class="monospaced">
ifdef::doctype-manpage[]
&#10;.ft C&#10;
endif::doctype-manpage[]
@ -53,7 +53,7 @@ ifdef::doctype-manpage[] @@ -53,7 +53,7 @@ ifdef::doctype-manpage[]
# The following two small workarounds insert a simple paragraph after screen
[listingblock]
<example><title>{title}</title>
<literallayout>
<literallayout class="monospaced">
|
</literallayout><simpara></simpara>
{title#}</example>

12
Documentation/git-config.txt

@ -54,16 +54,16 @@ configuration file by default, and options '--system', '--global', @@ -54,16 +54,16 @@ configuration file by default, and options '--system', '--global',
'--file <filename>' can be used to tell the command to write to
that location (you can say '--local' but that is the default).

This command will fail (with exit code ret) if:
This command will fail with non-zero status upon error. Some exit
codes are:

. The config file is invalid (ret=3),
. can not write to the config file (ret=4),
. no section or name was provided (ret=2),
. the section or key is invalid (ret=1),
. you try to unset an option which does not exist (ret=5),
. you try to unset/set an option for which multiple lines match (ret=5),
. you try to use an invalid regexp (ret=6), or
. you use '--global' option without $HOME being properly set (ret=128).
. you try to unset/set an option for which multiple lines match (ret=5), or
. you try to use an invalid regexp (ret=6).

On success, the command returns the exit code 0.

@ -267,7 +267,7 @@ Given a .git/config like this: @@ -267,7 +267,7 @@ Given a .git/config like this:

; Proxy settings
[core]
gitproxy="proxy-command" for kernel.org
gitproxy=proxy-command for kernel.org
gitproxy=default-proxy ; for all the rest

you can set the filemode to true with
@ -342,7 +342,7 @@ To actually match only values with an exclamation mark, you have to @@ -342,7 +342,7 @@ To actually match only values with an exclamation mark, you have to
To add a new proxy, without altering any of the existing ones, use

------------
% git config core.gitproxy '"proxy-command" for example.com'
% git config --add core.gitproxy '"proxy-command" for example.com'
------------

An example to use customized color from the configuration in your

9
Documentation/git-submodule.txt

@ -149,6 +149,11 @@ submodule with the `--init` option. @@ -149,6 +149,11 @@ submodule with the `--init` option.
+
If `--recursive` is specified, this command will recurse into the
registered submodules, and update any nested submodules within.
+
If `--force` is specified, the submodule will be checked out (using
`git checkout --force` if appropriate), even if the commit specified in the
index of the containing repository already matches the commit checked out in
the submodule.

summary::
Show commit summary between the given commit (defaults to HEAD) and
@ -210,7 +215,9 @@ OPTIONS @@ -210,7 +215,9 @@ OPTIONS
This option is only valid for add and update commands.
When running add, allow adding an otherwise ignored submodule path.
When running update, throw away local changes in submodules when
switching to a different commit.
switching to a different commit; and always run a checkout operation
in the submodule, even if the commit listed in the index of the
containing repository matches the commit checked out in the submodule.

--cached::
This option is only valid for status and summary commands. These

3
Documentation/git.txt

@ -48,9 +48,10 @@ Documentation for older releases are available here: @@ -48,9 +48,10 @@ Documentation for older releases are available here:
* release notes for
link:RelNotes/1.7.12.txt[1.7.12].

* link:v1.7.11.5/git.html[documentation for release 1.7.11.5]
* link:v1.7.11.6/git.html[documentation for release 1.7.11.6]

* release notes for
link:RelNotes/1.7.11.6.txt[1.7.11.6],
link:RelNotes/1.7.11.5.txt[1.7.11.5],
link:RelNotes/1.7.11.4.txt[1.7.11.4],
link:RelNotes/1.7.11.3.txt[1.7.11.3],

2
Documentation/user-manual.conf

@ -14,7 +14,7 @@ ifdef::backend-docbook[] @@ -14,7 +14,7 @@ ifdef::backend-docbook[]
# "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this.
[listingblock]
<example><title>{title}</title>
<literallayout>
<literallayout class="monospaced">
|
</literallayout>
{title#}</example>

1
builtin/apply.c

@ -188,7 +188,6 @@ struct patch { @@ -188,7 +188,6 @@ struct patch {
int is_new, is_delete; /* -1 = unknown, 0 = false, 1 = true */
int rejected;
unsigned ws_rule;
unsigned long deflate_origlen;
int lines_added, lines_deleted;
int score;
unsigned int is_toplevel_relative:1;

9
builtin/blame.c

@ -407,8 +407,7 @@ static struct origin *find_origin(struct scoreboard *sb, @@ -407,8 +407,7 @@ static struct origin *find_origin(struct scoreboard *sb,
paths[1] = NULL;

diff_tree_setup_paths(paths, &diff_opts);
if (diff_setup_done(&diff_opts) < 0)
die("diff-setup");
diff_setup_done(&diff_opts);

if (is_null_sha1(origin->commit->object.sha1))
do_diff_cache(parent->tree->object.sha1, &diff_opts);
@ -494,8 +493,7 @@ static struct origin *find_rename(struct scoreboard *sb, @@ -494,8 +493,7 @@ static struct origin *find_rename(struct scoreboard *sb,
diff_opts.single_follow = origin->path;
paths[0] = NULL;
diff_tree_setup_paths(paths, &diff_opts);
if (diff_setup_done(&diff_opts) < 0)
die("diff-setup");
diff_setup_done(&diff_opts);

if (is_null_sha1(origin->commit->object.sha1))
do_diff_cache(parent->tree->object.sha1, &diff_opts);
@ -1075,8 +1073,7 @@ static int find_copy_in_parent(struct scoreboard *sb, @@ -1075,8 +1073,7 @@ static int find_copy_in_parent(struct scoreboard *sb,

paths[0] = NULL;
diff_tree_setup_paths(paths, &diff_opts);
if (diff_setup_done(&diff_opts) < 0)
die("diff-setup");
diff_setup_done(&diff_opts);

/* Try "find copies harder" on new path if requested;
* we do not want to use diffcore_rename() actually to

3
builtin/checkout.c

@ -316,8 +316,7 @@ static void show_local_changes(struct object *head, struct diff_options *opts) @@ -316,8 +316,7 @@ static void show_local_changes(struct object *head, struct diff_options *opts)
init_revisions(&rev, NULL);
rev.diffopt.flags = opts->flags;
rev.diffopt.output_format |= DIFF_FORMAT_NAME_STATUS;
if (diff_setup_done(&rev.diffopt) < 0)
die(_("diff_setup_done failed"));
diff_setup_done(&rev.diffopt);
add_pending_object(&rev, head, NULL);
run_diff_index(&rev, 0);
}

8
builtin/config.c

@ -160,7 +160,7 @@ static int show_config(const char *key_, const char *value_, void *cb) @@ -160,7 +160,7 @@ static int show_config(const char *key_, const char *value_, void *cb)

static int get_value(const char *key_, const char *regex_)
{
int ret = -1;
int ret = CONFIG_GENERIC_ERROR;
char *global = NULL, *xdg = NULL, *repo_config = NULL;
const char *system_wide = NULL, *local;
struct config_include_data inc = CONFIG_INCLUDE_INIT;
@ -196,12 +196,15 @@ static int get_value(const char *key_, const char *regex_) @@ -196,12 +196,15 @@ static int get_value(const char *key_, const char *regex_)
if (regcomp(key_regexp, key, REG_EXTENDED)) {
fprintf(stderr, "Invalid key pattern: %s\n", key_);
free(key);
ret = CONFIG_INVALID_PATTERN;
goto free_strings;
}
} else {
if (git_config_parse_key(key_, &key, NULL))
if (git_config_parse_key(key_, &key, NULL)) {
ret = CONFIG_INVALID_KEY;
goto free_strings;
}
}

if (regex_) {
if (regex_[0] == '!') {
@ -212,6 +215,7 @@ static int get_value(const char *key_, const char *regex_) @@ -212,6 +215,7 @@ static int get_value(const char *key_, const char *regex_)
regexp = (regex_t*)xmalloc(sizeof(regex_t));
if (regcomp(regexp, regex_, REG_EXTENDED)) {
fprintf(stderr, "Invalid pattern: %s\n", regex_);
ret = CONFIG_INVALID_PATTERN;
goto free_strings;
}
}

3
builtin/diff.c

@ -302,8 +302,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) @@ -302,8 +302,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
argc = setup_revisions(argc, argv, &rev, NULL);
if (!rev.diffopt.output_format) {
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
if (diff_setup_done(&rev.diffopt) < 0)
die(_("diff_setup_done failed"));
diff_setup_done(&rev.diffopt);
}

DIFF_OPT_SET(&rev.diffopt, RECURSIVE);

3
builtin/merge.c

@ -404,8 +404,7 @@ static void finish(struct commit *head_commit, @@ -404,8 +404,7 @@ static void finish(struct commit *head_commit,
opts.output_format |=
DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
opts.detect_rename = DIFF_DETECT_RENAME;
if (diff_setup_done(&opts) < 0)
die(_("diff_setup_done failed"));
diff_setup_done(&opts);
diff_tree_sha1(head, new_head, "", &opts);
diffcore_std(&opts);
diff_flush(&opts);

1
cache.h

@ -1110,6 +1110,7 @@ extern int update_server_info(int); @@ -1110,6 +1110,7 @@ extern int update_server_info(int);
#define CONFIG_NO_WRITE 4
#define CONFIG_NOTHING_SET 5
#define CONFIG_INVALID_PATTERN 6
#define CONFIG_GENERIC_ERROR 7

typedef int (*config_fn_t)(const char *, const char *, void *);
extern int git_default_config(const char *, const char *, void *);

3
diff-no-index.c

@ -258,8 +258,7 @@ void diff_no_index(struct rev_info *revs, @@ -258,8 +258,7 @@ void diff_no_index(struct rev_info *revs,
DIFF_OPT_SET(&revs->diffopt, NO_INDEX);

revs->max_count = -2;
if (diff_setup_done(&revs->diffopt) < 0)
die("diff_setup_done failed");
diff_setup_done(&revs->diffopt);

setup_diff_pager(&revs->diffopt);
DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);

5
diff.c

@ -574,6 +574,7 @@ static void emit_rewrite_lines(struct emit_callback *ecb, @@ -574,6 +574,7 @@ static void emit_rewrite_lines(struct emit_callback *ecb,
if (!endp) {
const char *plain = diff_get_color(ecb->color_diff,
DIFF_PLAIN);
putc('\n', ecb->opt->file);
emit_line_0(ecb->opt, plain, reset, '\\',
nneof, strlen(nneof));
}
@ -3187,7 +3188,7 @@ void diff_setup(struct diff_options *options) @@ -3187,7 +3188,7 @@ void diff_setup(struct diff_options *options)
}
}

int diff_setup_done(struct diff_options *options)
void diff_setup_done(struct diff_options *options)
{
int count = 0;

@ -3286,8 +3287,6 @@ int diff_setup_done(struct diff_options *options) @@ -3286,8 +3287,6 @@ int diff_setup_done(struct diff_options *options)
options->output_format = DIFF_FORMAT_NO_OUTPUT;
DIFF_OPT_SET(options, EXIT_WITH_STATUS);
}

return 0;
}

static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)

2
diff.h

@ -246,7 +246,7 @@ extern int git_diff_ui_config(const char *var, const char *value, void *cb); @@ -246,7 +246,7 @@ extern int git_diff_ui_config(const char *var, const char *value, void *cb);
extern int diff_use_color_default;
extern void diff_setup(struct diff_options *);
extern int diff_opt_parse(struct diff_options *, const char **, int);
extern int diff_setup_done(struct diff_options *);
extern void diff_setup_done(struct diff_options *);

#define DIFF_DETECT_RENAME 1
#define DIFF_DETECT_COPY 2

123
git-mergetool.sh

@ -38,7 +38,8 @@ base_present () { @@ -38,7 +38,8 @@ base_present () {
}

cleanup_temp_files () {
if test "$1" = --save-backup ; then
if test "$1" = --save-backup
then
rm -rf -- "$MERGED.orig"
test -e "$BACKUP" && mv -- "$BACKUP" "$MERGED.orig"
rm -f -- "$LOCAL" "$REMOTE" "$BASE"
@ -53,24 +54,26 @@ describe_file () { @@ -53,24 +54,26 @@ describe_file () {
file="$3"

printf " {%s}: " "$branch"
if test -z "$mode"; then
if test -z "$mode"
then
echo "deleted"
elif is_symlink "$mode" ; then
elif is_symlink "$mode"
then
echo "a symbolic link -> '$(cat "$file")'"
elif is_submodule "$mode" ; then
elif is_submodule "$mode"
then
echo "submodule commit $file"
else
if base_present; then
elif base_present
then
echo "modified file"
else
echo "created file"
fi
fi
}


resolve_symlink_merge () {
while true; do
while true
do
printf "Use (l)ocal or (r)emote, or (a)bort? "
read ans || return 1
case "$ans" in
@ -94,8 +97,10 @@ resolve_symlink_merge () { @@ -94,8 +97,10 @@ resolve_symlink_merge () {
}

resolve_deleted_merge () {
while true; do
if base_present; then
while true
do
if base_present
then
printf "Use (m)odified or (d)eleted file, or (a)bort? "
else
printf "Use (c)reated or (d)eleted file, or (a)bort? "
@ -120,21 +125,26 @@ resolve_deleted_merge () { @@ -120,21 +125,26 @@ resolve_deleted_merge () {
}

resolve_submodule_merge () {
while true; do
while true
do
printf "Use (l)ocal or (r)emote, or (a)bort? "
read ans || return 1
case "$ans" in
[lL]*)
if ! local_present; then
if test -n "$(git ls-tree HEAD -- "$MERGED")"; then
if ! local_present
then
if test -n "$(git ls-tree HEAD -- "$MERGED")"
then
# Local isn't present, but it's a subdirectory
git ls-tree --full-name -r HEAD -- "$MERGED" | git update-index --index-info || exit $?
git ls-tree --full-name -r HEAD -- "$MERGED" |
git update-index --index-info || exit $?
else
test -e "$MERGED" && mv -- "$MERGED" "$BACKUP"
git update-index --force-remove "$MERGED"
cleanup_temp_files --save-backup
fi
elif is_submodule "$local_mode"; then
elif is_submodule "$local_mode"
then
stage_submodule "$MERGED" "$local_sha1"
else
git checkout-index -f --stage=2 -- "$MERGED"
@ -143,16 +153,22 @@ resolve_submodule_merge () { @@ -143,16 +153,22 @@ resolve_submodule_merge () {
return 0
;;
[rR]*)
if ! remote_present; then
if test -n "$(git ls-tree MERGE_HEAD -- "$MERGED")"; then
if ! remote_present
then
if test -n "$(git ls-tree MERGE_HEAD -- "$MERGED")"
then
# Remote isn't present, but it's a subdirectory
git ls-tree --full-name -r MERGE_HEAD -- "$MERGED" | git update-index --index-info || exit $?
git ls-tree --full-name -r MERGE_HEAD -- "$MERGED" |
git update-index --index-info || exit $?
else
test -e "$MERGED" && mv -- "$MERGED" "$BACKUP"
git update-index --force-remove "$MERGED"
fi
elif is_submodule "$remote_mode"; then
! is_submodule "$local_mode" && test -e "$MERGED" && mv -- "$MERGED" "$BACKUP"
elif is_submodule "$remote_mode"
then
! is_submodule "$local_mode" &&
test -e "$MERGED" &&
mv -- "$MERGED" "$BACKUP"
stage_submodule "$MERGED" "$remote_sha1"
else
test -e "$MERGED" && mv -- "$MERGED" "$BACKUP"
@ -172,11 +188,15 @@ resolve_submodule_merge () { @@ -172,11 +188,15 @@ resolve_submodule_merge () {
stage_submodule () {
path="$1"
submodule_sha1="$2"
mkdir -p "$path" || die "fatal: unable to create directory for module at $path"
mkdir -p "$path" ||
die "fatal: unable to create directory for module at $path"
# Find $path relative to work tree
work_tree_root=$(cd_to_toplevel && pwd)
work_rel_path=$(cd "$path" && GIT_WORK_TREE="${work_tree_root}" git rev-parse --show-prefix)
test -n "$work_rel_path" || die "fatal: unable to get path of module $path relative to work tree"
work_rel_path=$(cd "$path" &&
GIT_WORK_TREE="${work_tree_root}" git rev-parse --show-prefix
)
test -n "$work_rel_path" ||
die "fatal: unable to get path of module $path relative to work tree"
git update-index --add --replace --cacheinfo 160000 "$submodule_sha1" "${work_rel_path%/}" || die
}

@ -185,7 +205,8 @@ checkout_staged_file () { @@ -185,7 +205,8 @@ checkout_staged_file () {
"$(git checkout-index --temp --stage="$1" "$2" 2>/dev/null)" \
: '\([^ ]*\) ')

if test $? -eq 0 -a -n "$tmpfile" ; then
if test $? -eq 0 -a -n "$tmpfile"
then
mv -- "$(git rev-parse --show-cdup)$tmpfile" "$3"
else
>"$3"
@ -196,8 +217,10 @@ merge_file () { @@ -196,8 +217,10 @@ merge_file () {
MERGED="$1"

f=$(git ls-files -u -- "$MERGED")
if test -z "$f" ; then
if test ! -f "$MERGED" ; then
if test -z "$f"
then
if test ! -f "$MERGED"
then
echo "$MERGED: file not found"
else
echo "$MERGED: file does not need merging"
@ -215,7 +238,8 @@ merge_file () { @@ -215,7 +238,8 @@ merge_file () {
local_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $1;}')
remote_mode=$(git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $1;}')

if is_submodule "$local_mode" || is_submodule "$remote_mode"; then
if is_submodule "$local_mode" || is_submodule "$remote_mode"
then
echo "Submodule merge conflict for '$MERGED':"
local_sha1=$(git ls-files -u -- "$MERGED" | awk '{if ($3==2) print $2;}')
remote_sha1=$(git ls-files -u -- "$MERGED" | awk '{if ($3==3) print $2;}')
@ -232,7 +256,8 @@ merge_file () { @@ -232,7 +256,8 @@ merge_file () {
checkout_staged_file 2 "$MERGED" "$LOCAL"
checkout_staged_file 3 "$MERGED" "$REMOTE"

if test -z "$local_mode" -o -z "$remote_mode"; then
if test -z "$local_mode" -o -z "$remote_mode"
then
echo "Deleted merge conflict for '$MERGED':"
describe_file "$local_mode" "local" "$LOCAL"
describe_file "$remote_mode" "remote" "$REMOTE"
@ -240,7 +265,8 @@ merge_file () { @@ -240,7 +265,8 @@ merge_file () {
return
fi

if is_symlink "$local_mode" || is_symlink "$remote_mode"; then
if is_symlink "$local_mode" || is_symlink "$remote_mode"
then
echo "Symbolic link merge conflict for '$MERGED':"
describe_file "$local_mode" "local" "$LOCAL"
describe_file "$remote_mode" "remote" "$REMOTE"
@ -251,29 +277,34 @@ merge_file () { @@ -251,29 +277,34 @@ merge_file () {
echo "Normal merge conflict for '$MERGED':"
describe_file "$local_mode" "local" "$LOCAL"
describe_file "$remote_mode" "remote" "$REMOTE"
if "$prompt" = true; then
if "$prompt" = true
then
printf "Hit return to start merge resolution tool (%s): " "$merge_tool"
read ans || return 1
fi

if base_present; then
if base_present
then
present=true
else
present=false
fi

if ! run_merge_tool "$merge_tool" "$present"; then
if ! run_merge_tool "$merge_tool" "$present"
then
echo "merge of $MERGED failed" 1>&2
mv -- "$BACKUP" "$MERGED"

if test "$merge_keep_temporaries" = "false"; then
if test "$merge_keep_temporaries" = "false"
then
cleanup_temp_files
fi

return 1
fi

if test "$merge_keep_backup" = "true"; then
if test "$merge_keep_backup" = "true"
then
mv -- "$BACKUP" "$MERGED.orig"
else
rm -- "$BACKUP"
@ -361,16 +392,15 @@ do @@ -361,16 +392,15 @@ do
shift
done

prompt_after_failed_merge() {
while true; do
prompt_after_failed_merge () {
while true
do
printf "Continue merging other unresolved paths (y/n) ? "
read ans || return 1
case "$ans" in

[yY]*)
return 0
;;

[nN]*)
return 1
;;
@ -378,7 +408,8 @@ prompt_after_failed_merge() { @@ -378,7 +408,8 @@ prompt_after_failed_merge() {
done
}

if test -z "$merge_tool"; then
if test -z "$merge_tool"
then
merge_tool=$(get_merge_tool "$merge_tool") || exit
fi
merge_keep_backup="$(git config --bool mergetool.keepBackup || echo true)"
@ -388,7 +419,8 @@ last_status=0 @@ -388,7 +419,8 @@ last_status=0
rollup_status=0
files=

if test $# -eq 0 ; then
if test $# -eq 0
then
cd_to_toplevel

if test -e "$GIT_DIR/MERGE_RR"
@ -401,7 +433,8 @@ else @@ -401,7 +433,8 @@ else
files=$(git ls-files -u -- "$@" | sed -e 's/^[^ ]* //' | sort -u)
fi

if test -z "$files" ; then
if test -z "$files"
then
echo "No files need merging"
exit 0
fi
@ -413,13 +446,15 @@ IFS=' @@ -413,13 +446,15 @@ IFS='
'
for i in $files
do
if test $last_status -ne 0; then
if test $last_status -ne 0
then
prompt_after_failed_merge || exit 1
fi
printf "\n"
merge_file "$i"
last_status=$?
if test $last_status -ne 0; then
if test $last_status -ne 0
then
rollup_status=1
fi
done

1
git-stash.sh

@ -469,6 +469,7 @@ apply_stash () { @@ -469,6 +469,7 @@ apply_stash () {
else
# Merge conflict; keep the exit status from merge-recursive
status=$?
git rerere
if test -n "$INDEX_OPTION"
then
gettextln "Index was not unstashed." >&2

35
git-submodule.sh

@ -109,26 +109,48 @@ resolve_relative_url () @@ -109,26 +109,48 @@ resolve_relative_url ()
#
module_list()
{
git ls-files --error-unmatch --stage -- "$@" |
(
git ls-files --error-unmatch --stage -- "$@" ||
echo "unmatched pathspec exists"
) |
perl -e '
my %unmerged = ();
my ($null_sha1) = ("0" x 40);
my @out = ();
my $unmatched = 0;
while (<STDIN>) {
if (/^unmatched pathspec/) {
$unmatched = 1;
next;
}
chomp;
my ($mode, $sha1, $stage, $path) =
/^([0-7]+) ([0-9a-f]{40}) ([0-3])\t(.*)$/;
next unless $mode eq "160000";
if ($stage ne "0") {
if (!$unmerged{$path}++) {
print "$mode $null_sha1 U\t$path\n";
push @out, "$mode $null_sha1 U\t$path\n";
}
next;
}
print "$_\n";
push @out, "$_\n";
}
if ($unmatched) {
print "#unmatched\n";
} else {
print for (@out);
}
'
}

die_if_unmatched ()
{
if test "$1" = "#unmatched"
then
exit 1
fi
}

#
# Map submodule path to submodule name
#
@ -385,6 +407,7 @@ cmd_foreach() @@ -385,6 +407,7 @@ cmd_foreach()
module_list |
while read mode sha1 stage sm_path
do
die_if_unmatched "$mode"
if test -e "$sm_path"/.git
then
say "$(eval_gettext "Entering '\$prefix\$sm_path'")"
@ -437,6 +460,7 @@ cmd_init() @@ -437,6 +460,7 @@ cmd_init()
module_list "$@" |
while read mode sha1 stage sm_path
do
die_if_unmatched "$mode"
name=$(module_name "$sm_path") || exit

# Copy url setting when it is not set yet
@ -537,6 +561,7 @@ cmd_update() @@ -537,6 +561,7 @@ cmd_update()
err=
while read mode sha1 stage sm_path
do
die_if_unmatched "$mode"
if test "$stage" = U
then
echo >&2 "Skipping unmerged submodule $sm_path"
@ -578,7 +603,7 @@ Maybe you want to use 'update --init'?")" @@ -578,7 +603,7 @@ Maybe you want to use 'update --init'?")"
die "$(eval_gettext "Unable to find current revision in submodule path '\$sm_path'")"
fi

if test "$subsha1" != "$sha1"
if test "$subsha1" != "$sha1" -o -n "$force"
then
subforce=$force
# If we don't already have a -f flag and the submodule has never been checked out
@ -932,6 +957,7 @@ cmd_status() @@ -932,6 +957,7 @@ cmd_status()
module_list "$@" |
while read mode sha1 stage sm_path
do
die_if_unmatched "$mode"
name=$(module_name "$sm_path") || exit
url=$(git config submodule."$name".url)
displaypath="$prefix$sm_path"
@ -1000,6 +1026,7 @@ cmd_sync() @@ -1000,6 +1026,7 @@ cmd_sync()
module_list "$@" |
while read mode sha1 stage sm_path
do
die_if_unmatched "$mode"
name=$(module_name "$sm_path")
url=$(git config -f .gitmodules --get submodule."$name".url)


22
merge-recursive.c

@ -493,8 +493,7 @@ static struct string_list *get_renames(struct merge_options *o, @@ -493,8 +493,7 @@ static struct string_list *get_renames(struct merge_options *o,
opts.rename_score = o->rename_score;
opts.show_rename_progress = o->show_rename_progress;
opts.output_format = DIFF_FORMAT_NO_OUTPUT;
if (diff_setup_done(&opts) < 0)
die(_("diff setup failed"));
diff_setup_done(&opts);
diff_tree_sha1(o_tree->object.sha1, tree->object.sha1, "", &opts);
diffcore_std(&opts);
if (opts.needed_rename_limit > o->needed_rename_limit)
@ -614,23 +613,6 @@ static char *unique_path(struct merge_options *o, const char *path, const char * @@ -614,23 +613,6 @@ static char *unique_path(struct merge_options *o, const char *path, const char *
return newpath;
}

static void flush_buffer(int fd, const char *buf, unsigned long size)
{
while (size > 0) {
long ret = write_in_full(fd, buf, size);
if (ret < 0) {
/* Ignore epipe */
if (errno == EPIPE)
break;
die_errno("merge-recursive");
} else if (!ret) {
die(_("merge-recursive: disk full?"));
}
size -= ret;
buf += ret;
}
}

static int dir_in_way(const char *path, int check_working_copy)
{
int pos, pathlen = strlen(path);
@ -789,7 +771,7 @@ static void update_file_flags(struct merge_options *o, @@ -789,7 +771,7 @@ static void update_file_flags(struct merge_options *o,
fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);
if (fd < 0)
die_errno(_("failed to open '%s'"), path);
flush_buffer(fd, buf, size);
write_in_full(fd, buf, size);
close(fd);
} else if (S_ISLNK(mode)) {
char *lnk = xmemdupz(buf, size);

6
notes-merge.c

@ -126,8 +126,7 @@ static struct notes_merge_pair *diff_tree_remote(struct notes_merge_options *o, @@ -126,8 +126,7 @@ static struct notes_merge_pair *diff_tree_remote(struct notes_merge_options *o,
diff_setup(&opt);
DIFF_OPT_SET(&opt, RECURSIVE);
opt.output_format = DIFF_FORMAT_NO_OUTPUT;
if (diff_setup_done(&opt) < 0)
die("diff_setup_done failed");
diff_setup_done(&opt);
diff_tree_sha1(base, remote, "", &opt);
diffcore_std(&opt);

@ -190,8 +189,7 @@ static void diff_tree_local(struct notes_merge_options *o, @@ -190,8 +189,7 @@ static void diff_tree_local(struct notes_merge_options *o,
diff_setup(&opt);
DIFF_OPT_SET(&opt, RECURSIVE);
opt.output_format = DIFF_FORMAT_NO_OUTPUT;
if (diff_setup_done(&opt) < 0)
die("diff_setup_done failed");
diff_setup_done(&opt);
diff_tree_sha1(base, local, "", &opt);
diffcore_std(&opt);


3
patch-ids.c

@ -39,8 +39,7 @@ int init_patch_ids(struct patch_ids *ids) @@ -39,8 +39,7 @@ int init_patch_ids(struct patch_ids *ids)
memset(ids, 0, sizeof(*ids));
diff_setup(&ids->diffopts);
DIFF_OPT_SET(&ids->diffopts, RECURSIVE);
if (diff_setup_done(&ids->diffopts) < 0)
return error("diff_setup_done failed");
diff_setup_done(&ids->diffopts);
return 0;
}


6
read-cache.c

@ -1414,11 +1414,9 @@ int read_index_from(struct index_state *istate, const char *path) @@ -1414,11 +1414,9 @@ int read_index_from(struct index_state *istate, const char *path)
size_t mmap_size;
struct strbuf previous_name_buf = STRBUF_INIT, *previous_name;

errno = EBUSY;
if (istate->initialized)
return istate->cache_nr;

errno = ENOENT;
istate->timestamp.sec = 0;
istate->timestamp.nsec = 0;
fd = open(path, O_RDONLY);
@ -1431,15 +1429,14 @@ int read_index_from(struct index_state *istate, const char *path) @@ -1431,15 +1429,14 @@ int read_index_from(struct index_state *istate, const char *path)
if (fstat(fd, &st))
die_errno("cannot stat the open index");

errno = EINVAL;
mmap_size = xsize_t(st.st_size);
if (mmap_size < sizeof(struct cache_header) + 20)
die("index file smaller than expected");

mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
close(fd);
if (mmap == MAP_FAILED)
die_errno("unable to map index file");
close(fd);

hdr = mmap;
if (verify_hdr(hdr, mmap_size) < 0)
@ -1495,7 +1492,6 @@ int read_index_from(struct index_state *istate, const char *path) @@ -1495,7 +1492,6 @@ int read_index_from(struct index_state *istate, const char *path)

unmap:
munmap(mmap, mmap_size);
errno = EINVAL;
die("index file corrupt");
}


3
revision.c

@ -1863,8 +1863,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s @@ -1863,8 +1863,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
if (revs->combine_merges)
revs->ignore_merges = 0;
revs->diffopt.abbrev = revs->abbrev;
if (diff_setup_done(&revs->diffopt) < 0)
die("diff_setup_done failed");
diff_setup_done(&revs->diffopt);

compile_grep_patterns(&revs->grep_filter);


2
run-command.c

@ -139,6 +139,8 @@ int sane_execvp(const char *file, char * const argv[]) @@ -139,6 +139,8 @@ int sane_execvp(const char *file, char * const argv[])
*/
if (errno == EACCES && !strchr(file, '/'))
errno = exists_in_PATH(file) ? EACCES : ENOENT;
else if (errno == ENOTDIR && !strchr(file, '/'))
errno = ENOENT;
return -1;
}


3
submodule.c

@ -574,8 +574,7 @@ static void calculate_changed_submodule_paths(void) @@ -574,8 +574,7 @@ static void calculate_changed_submodule_paths(void)
DIFF_OPT_SET(&diff_opts, RECURSIVE);
diff_opts.output_format |= DIFF_FORMAT_CALLBACK;
diff_opts.format_callback = submodule_collect_changed_cb;
if (diff_setup_done(&diff_opts) < 0)
die("diff_setup_done failed");
diff_setup_done(&diff_opts);
diff_tree_sha1(parent->item->object.sha1, commit->object.sha1, "", &diff_opts);
diffcore_std(&diff_opts);
diff_flush(&diff_opts);

18
t/t3401-rebase-partial.sh

@ -47,7 +47,23 @@ test_expect_success 'rebase ignores empty commit' ' @@ -47,7 +47,23 @@ test_expect_success 'rebase ignores empty commit' '
git commit --allow-empty -m empty &&
test_commit D &&
git rebase C &&
test $(git log --format=%s C..) = "D"
test "$(git log --format=%s C..)" = "D"
'

test_expect_success 'rebase --keep-empty' '
git reset --hard D &&
git rebase --keep-empty C &&
test "$(git log --format=%s C..)" = "D
empty"
'

test_expect_success 'rebase --keep-empty keeps empty even if already in upstream' '
git reset --hard A &&
git commit --allow-empty -m also-empty &&
git rebase --keep-empty D &&
test "$(git log --format=%s A..)" = "also-empty
D
empty"
'

test_done

30
t/t4022-diff-rewrite.sh

@ -66,5 +66,35 @@ test_expect_success 'suppress deletion diff with -B -D' ' @@ -66,5 +66,35 @@ test_expect_success 'suppress deletion diff with -B -D' '
grep -v "Linus Torvalds" actual
'

test_expect_success 'prepare a file that ends with an incomplete line' '
test_seq 1 99 >seq &&
printf 100 >>seq &&
git add seq &&
git commit seq -m seq
'

test_expect_success 'rewrite the middle 90% of sequence file and terminate with newline' '
test_seq 1 5 >seq &&
test_seq 9331 9420 >>seq &&
test_seq 96 100 >>seq
'

test_expect_success 'confirm that sequence file is considered a rewrite' '
git diff -B seq >res &&
grep "dissimilarity index" res
'

test_expect_success 'no newline at eof is on its own line without -B' '
git diff seq >res &&
grep "^\\\\ " res &&
! grep "^..*\\\\ " res
'

test_expect_success 'no newline at eof is on its own line with -B' '
git diff -B seq >res &&
grep "^\\\\ " res &&
! grep "^..*\\\\ " res
'

test_done


26
t/t7400-submodule-basic.sh

@ -258,6 +258,27 @@ test_expect_success 'init should register submodule url in .git/config' ' @@ -258,6 +258,27 @@ test_expect_success 'init should register submodule url in .git/config' '
test_cmp expect url
'

test_failure_with_unknown_submodule () {
test_must_fail git submodule $1 no-such-submodule 2>output.err &&
grep "^error: .*no-such-submodule" output.err
}

test_expect_success 'init should fail with unknown submodule' '
test_failure_with_unknown_submodule init
'

test_expect_success 'update should fail with unknown submodule' '
test_failure_with_unknown_submodule update
'

test_expect_success 'status should fail with unknown submodule' '
test_failure_with_unknown_submodule status
'

test_expect_success 'sync should fail with unknown submodule' '
test_failure_with_unknown_submodule sync
'

test_expect_success 'update should fail when path is used by a file' '
echo hello >expect &&

@ -418,10 +439,7 @@ test_expect_success 'moving to a commit without submodule does not leave empty d @@ -418,10 +439,7 @@ test_expect_success 'moving to a commit without submodule does not leave empty d
'

test_expect_success 'submodule <invalid-path> warns' '

git submodule no-such-submodule 2> output.err &&
grep "^error: .*no-such-submodule" output.err

test_failure_with_unknown_submodule
'

test_expect_success 'add submodules without specifying an explicit path' '

28
t/t7406-submodule-update.sh

@ -123,6 +123,18 @@ test_expect_success 'submodule update should throw away changes with --force ' ' @@ -123,6 +123,18 @@ test_expect_success 'submodule update should throw away changes with --force ' '
)
'

test_expect_success 'submodule update --force forcibly checks out submodules' '
(cd super &&
(cd submodule &&
rm -f file
) &&
git submodule update --force submodule &&
(cd submodule &&
test "$(git status -s file)" = ""
)
)
'

test_expect_success 'submodule update --rebase staying on master' '
(cd super/submodule &&
git checkout master
@ -367,7 +379,7 @@ test_expect_success 'submodule update continues after checkout error' ' @@ -367,7 +379,7 @@ test_expect_success 'submodule update continues after checkout error' '
git submodule init &&
git commit -am "new_submodule" &&
(cd submodule2 &&
git rev-parse --max-count=1 HEAD > ../expect
git rev-parse --verify HEAD >../expect
) &&
(cd submodule &&
test_commit "update_submodule" file
@ -384,7 +396,7 @@ test_expect_success 'submodule update continues after checkout error' ' @@ -384,7 +396,7 @@ test_expect_success 'submodule update continues after checkout error' '
git checkout HEAD^ &&
test_must_fail git submodule update &&
(cd submodule2 &&
git rev-parse --max-count=1 HEAD > ../actual
git rev-parse --verify HEAD >../actual
) &&
test_cmp expect actual
)
@ -413,7 +425,7 @@ test_expect_success 'submodule update continues after recursive checkout error' @@ -413,7 +425,7 @@ test_expect_success 'submodule update continues after recursive checkout error'
test_commit "update_submodule_again_again" file
) &&
(cd submodule2 &&
git rev-parse --max-count=1 HEAD > ../expect &&
git rev-parse --verify HEAD >../expect &&
test_commit "update_submodule2_again" file
) &&
git add submodule &&
@ -428,7 +440,7 @@ test_expect_success 'submodule update continues after recursive checkout error' @@ -428,7 +440,7 @@ test_expect_success 'submodule update continues after recursive checkout error'
) &&
test_must_fail git submodule update --recursive &&
(cd submodule2 &&
git rev-parse --max-count=1 HEAD > ../actual
git rev-parse --verify HEAD >../actual
) &&
test_cmp expect actual
)
@ -460,12 +472,12 @@ test_expect_success 'submodule update exit immediately in case of merge conflict @@ -460,12 +472,12 @@ test_expect_success 'submodule update exit immediately in case of merge conflict
) &&
git checkout HEAD^ &&
(cd submodule2 &&
git rev-parse --max-count=1 HEAD > ../expect
git rev-parse --verify HEAD >../expect
) &&
git config submodule.submodule.update merge &&
test_must_fail git submodule update &&
(cd submodule2 &&
git rev-parse --max-count=1 HEAD > ../actual
git rev-parse --verify HEAD >../actual
) &&
test_cmp expect actual
)
@ -495,12 +507,12 @@ test_expect_success 'submodule update exit immediately after recursive rebase er @@ -495,12 +507,12 @@ test_expect_success 'submodule update exit immediately after recursive rebase er
) &&
git checkout HEAD^ &&
(cd submodule2 &&
git rev-parse --max-count=1 HEAD > ../expect
git rev-parse --verify HEAD >../expect
) &&
git config submodule.submodule.update rebase &&
test_must_fail git submodule update &&
(cd submodule2 &&
git rev-parse --max-count=1 HEAD > ../actual
git rev-parse --verify HEAD >../actual
) &&
test_cmp expect actual
)

38
t/t7610-mergetool.sh

@ -55,6 +55,16 @@ test_expect_success 'setup' ' @@ -55,6 +55,16 @@ test_expect_success 'setup' '
git rm file12 &&
git commit -m "branch1 changes" &&

git checkout -b stash1 master &&
echo stash1 change file11 >file11 &&
git add file11 &&
git commit -m "stash1 changes" &&

git checkout -b stash2 master &&
echo stash2 change file11 >file11 &&
git add file11 &&
git commit -m "stash2 changes" &&

git checkout master &&
git submodule update -N &&
echo master updated >file1 &&
@ -193,7 +203,35 @@ test_expect_success 'mergetool skips resolved paths when rerere is active' ' @@ -193,7 +203,35 @@ test_expect_success 'mergetool skips resolved paths when rerere is active' '
git reset --hard
'

test_expect_success 'conflicted stash sets up rerere' '
git config rerere.enabled true &&
git checkout stash1 &&
echo "Conflicting stash content" >file11 &&
git stash &&

git checkout --detach stash2 &&
test_must_fail git stash apply &&

test -n "$(git ls-files -u)" &&
conflicts="$(git rerere remaining)" &&
test "$conflicts" = "file11" &&
output="$(git mergetool --no-prompt)" &&
test "$output" != "No files need merging" &&

git commit -am "save the stash resolution" &&

git reset --hard stash2 &&
test_must_fail git stash apply &&

test -n "$(git ls-files -u)" &&
conflicts="$(git rerere remaining)" &&
test -z "$conflicts" &&
output="$(git mergetool --no-prompt)" &&
test "$output" = "No files need merging"
'

test_expect_success 'mergetool takes partial path' '
git reset --hard
git config rerere.enabled false &&
git checkout -b test12 branch1 &&
git submodule update -N &&

3
tree-diff.c

@ -212,8 +212,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co @@ -212,8 +212,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
diff_opts.rename_score = opt->rename_score;
paths[0] = NULL;
diff_tree_setup_paths(paths, &diff_opts);
if (diff_setup_done(&diff_opts) < 0)
die("unable to set up diff options to follow renames");
diff_setup_done(&diff_opts);
diff_tree(t1, t2, base, &diff_opts);
diffcore_std(&diff_opts);
diff_tree_release_paths(&diff_opts);

Loading…
Cancel
Save