diff options
67 files changed, 724 insertions, 254 deletions
diff --git a/Documentation/RelNotes-1.6.5.8.txt b/Documentation/RelNotes-1.6.5.8.txt new file mode 100644 index 0000000000..8b24bebb96 --- /dev/null +++ b/Documentation/RelNotes-1.6.5.8.txt @@ -0,0 +1,28 @@ +Git v1.6.5.8 Release Notes +========================== + +Fixes since v1.6.5.7 +-------------------- + +* "git count-objects" did not handle packfiles that are bigger than 4G on + platforms with 32-bit off_t. + +* "git rebase -i" did not abort cleanly if it failed to launch the editor. + +* "git blame" did not work well when commit lacked the author name. + +* "git fast-import" choked when handling a tag that points at an object + that is not a commit. + +* "git reset --hard" did not work correctly when GIT_WORK_TREE environment + variable is used to point at the root of the true work tree. + +* "git grep" fed a buffer that is not NUL-terminated to underlying + regexec(). + +* "git checkout -m other" while on a branch that does not have any commit + segfaulted, instead of failing. + +* "git branch -a other" should have diagnosed the command as an error. + +Other minor documentation updates are also included. diff --git a/Documentation/RelNotes-1.6.6.1.txt b/Documentation/RelNotes-1.6.6.1.txt new file mode 100644 index 0000000000..f1d0a4ae2d --- /dev/null +++ b/Documentation/RelNotes-1.6.6.1.txt @@ -0,0 +1,37 @@ +Git v1.6.6.1 Release Notes +========================== + +Fixes since v1.6.6 +------------------ + + * "git blame" did not work well when commit lacked the author name. + + * "git branch -a name" wasn't diagnosed as an error. + + * "git count-objects" did not handle packfiles that are bigger than 4G on + platforms with 32-bit off_t. + + * "git checkout -m other" while on a branch that does not have any commit + segfaulted, instead of failing. + + * "git fast-import" choked when fed a tag that do not point at a + commit. + + * "git grep" finding from work tree files could have fed garbage to + the underlying regexec(3). + + * "git grep -L" didn't show empty files (they should never match, and + they should always appear in -L output as unmatching). + + * "git rebase -i" did not abort cleanly if it failed to launch the editor. + + * "git reset --hard" did not work correctly when GIT_WORK_TREE environment + variable is used to point at the root of the true work tree. + + * http-backend was not listed in the command list in the documentation. + + * Building on FreeBSD (both 7 and 8) needs OLD_ICONV set in the Makefile + + * "git checkout -m some-branch" while on an unborn branch crashed. + +Other minor documentation updates are included. diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 76fc84d878..c686f8646b 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -280,6 +280,20 @@ people play with it without having to pick up and apply the patch to their trees themselves. ------------------------------------------------ +Know the status of your patch after submission + +* You can use Git itself to find out when your patch is merged in + master. 'git pull --rebase' will automatically skip already-applied + patches, and will let you know. This works only if you rebase on top + of the branch in which your patch has been merged (i.e. it will not + tell you if your patch is merged in pu if you rebase on top of + master). + +* Read the git mailing list, the maintainer regularly posts messages + entitled "What's cooking in git.git" and "What's in git.git" giving + the status of various proposed changes. + +------------------------------------------------ MUA specific hints Some of patches I receive or pick up from the list share common diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt index 1625ffce6a..4833cac4b9 100644 --- a/Documentation/blame-options.txt +++ b/Documentation/blame-options.txt @@ -98,8 +98,10 @@ commit. files that were modified in the same commit. This is useful when you reorganize your program and move code around across files. When this option is given twice, - the command additionally looks for copies from all other - files in the parent for the commit that creates the file. + the command additionally looks for copies from other + files in the commit that creates the file. When this + option is given three times, the command additionally + looks for copies from other files in any commit. + <num> is optional but it is the lower bound on the number of alphanumeric characters that git must detect as moving diff --git a/Documentation/config.txt b/Documentation/config.txt index a1e36d7e42..f7728ec40c 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -297,17 +297,24 @@ false), while all other repositories are assumed to be bare (bare = true). core.worktree:: - Set the path to the working tree. The value will not be - used in combination with repositories found automatically in - a .git directory (i.e. $GIT_DIR is not set). + Set the path to the root of the work tree. This can be overridden by the GIT_WORK_TREE environment variable and the '--work-tree' command line option. It can be - a absolute path or relative path to the directory specified by - --git-dir or GIT_DIR. - Note: If --git-dir or GIT_DIR are specified but none of + an absolute path or a relative path to the .git directory, + either specified by --git-dir or GIT_DIR, or automatically + discovered. + If --git-dir or GIT_DIR are specified but none of --work-tree, GIT_WORK_TREE and core.worktree is specified, - the current working directory is regarded as the top directory - of your working tree. + the current working directory is regarded as the root of the + work tree. ++ +Note that this variable is honored even when set in a configuration +file in a ".git" subdirectory of a directory, and its value differs +from the latter directory (e.g. "/path/to/.git/config" has +core.worktree set to "/different/path"), which is most likely a +misconfiguration. Running git commands in "/path/to" directory will +still use "/different/path" as the root of the work tree and can cause +great confusion to the users. core.logAllRefUpdates:: Enable the reflog. Updates to a ref <ref> is logged to the file @@ -530,7 +537,7 @@ apply.whitespace:: as the '--whitespace' option. See linkgit:git-apply[1]. branch.autosetupmerge:: - Tells 'git-branch' and 'git-checkout' to setup new branches + Tells 'git-branch' and 'git-checkout' to set up new branches so that linkgit:git-pull[1] will appropriately merge from the starting point branch. Note that even if this option is not set, this behavior can be chosen per-branch using the `--track` @@ -718,7 +725,7 @@ diff.autorefreshindex:: contents in the work tree match the contents in the index. This option defaults to true. Note that this affects only 'git-diff' Porcelain, and not lower level - 'diff' commands, such as 'git-diff-files'. + 'diff' commands such as 'git-diff-files'. diff.external:: If this config variable is set, diff generation is not @@ -834,8 +841,8 @@ format.pretty:: format.thread:: The default threading style for 'git-format-patch'. Can be - either a boolean value, `shallow` or `deep`. `shallow` - threading makes every mail a reply to the head of the series, + a boolean value, or `shallow` or `deep`. `shallow` threading + makes every mail a reply to the head of the series, where the head is chosen from the cover letter, the `\--in-reply-to`, and the first patch mail, in this order. `deep` threading makes every mail a reply to the previous one. @@ -868,15 +875,12 @@ gc.autopacklimit:: default value is 50. Setting this to 0 disables it. gc.packrefs:: - 'git-gc' does not run `git pack-refs` in a bare repository by - default so that older dumb-transport clients can still fetch - from the repository. Setting this to `true` lets 'git-gc' - to run `git pack-refs`. Setting this to `false` tells - 'git-gc' never to run `git pack-refs`. The default setting is - `notbare`. Enable it only when you know you do not have to - support such clients. The default setting will change to `true` - at some stage, and setting this to `false` will continue to - prevent `git pack-refs` from being run from 'git-gc'. + Running `git pack-refs` in a repository renders it + unclonable by Git versions prior to 1.5.1.2 over dumb + transports such as HTTP. This variable determines whether + 'git gc' runs `git pack-refs`. This can be set to "nobare" + to enable it within all non-bare repos or it can be set to a + boolean value. The default is `true`. gc.pruneexpire:: When 'git-gc' is run, it will call 'prune --expire 2.weeks.ago'. diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt index e93e606f45..d0b279b829 100644 --- a/Documentation/git-add.txt +++ b/Documentation/git-add.txt @@ -14,28 +14,32 @@ SYNOPSIS DESCRIPTION ----------- -This command adds the current content of new or modified files to the -index, thus staging that content for inclusion in the next commit. +This command updates the index using the current content found in +the working tree, to prepare the content staged for the next commit. +It typically adds the current content of existing paths as a whole, +but with some options it can also be used to add content with +only part of the changes made to the working tree files applied, or +remove paths that do not exist in the working tree anymore. The "index" holds a snapshot of the content of the working tree, and it is this snapshot that is taken as the contents of the next commit. Thus after making any changes to the working directory, and before running -the commit command, you must use the 'add' command to add any new or +the commit command, you must use the `add` command to add any new or modified files to the index. This command can be performed multiple times before a commit. It only adds the content of the specified file(s) at the time the add command is run; if you want subsequent changes included in the next commit, then -you must run 'git add' again to add the new content to the index. +you must run `git add` again to add the new content to the index. -The 'git status' command can be used to obtain a summary of which +The `git status` command can be used to obtain a summary of which files have changes that are staged for the next commit. -The 'git add' command will not add ignored files by default. If any -ignored files were explicitly specified on the command line, 'git add' +The `git add` command will not add ignored files by default. If any +ignored files were explicitly specified on the command line, `git add` will fail with a list of ignored files. Ignored files reached by directory recursion or filename globbing performed by Git (quote your -globs before the shell) will be silently ignored. The 'add' command can +globs before the shell) will be silently ignored. The `add` command can be used to add ignored files with the `-f` (force) option. Please see linkgit:git-commit[1] for alternative ways to add content to a @@ -92,28 +96,31 @@ apply. -u:: --update:: - Update only files that git already knows about, staging modified - content for commit and marking deleted files for removal. This - is similar - to what "git commit -a" does in preparation for making a commit, - except that the update is limited to paths specified on the - command line. If no paths are specified, all tracked files in the - current directory and its subdirectories are updated. + Only match <filepattern> against already tracked files in + the index rather than the working tree. That means that it + will never stage new files, but that it will stage modified + new contents of tracked files and that it will remove files + from the index if the corresponding files in the working tree + have been removed. ++ +If no <filepattern> is given, default to "."; in other words, +update all tracked files in the current directory and its +subdirectories. -A:: --all:: - Update files that git already knows about (same as '\--update') - and add all untracked files that are not ignored by '.gitignore' - mechanism. - + Like `-u`, but match <filepattern> against files in the + working tree in addition to the index. That means that it + will find new files as well as staging modified content and + removing files that are no longer in the working tree. -N:: --intent-to-add:: Record only the fact that the path will be added later. An entry for the path is placed in the index with no content. This is useful for, among other things, showing the unstaged content of - such files with 'git diff' and committing them with 'git commit - -a'. + such files with `git diff` and committing them with `git commit + -a`. --refresh:: Don't add the file(s), but only refresh their stat() @@ -133,7 +140,7 @@ apply. Configuration ------------- -The optional configuration variable 'core.excludesfile' indicates a path to a +The optional configuration variable `core.excludesfile` indicates a path to a file containing patterns of file names to exclude from git-add, similar to $GIT_DIR/info/exclude. Patterns in the exclude file are used in addition to those in info/exclude. See linkgit:gitrepository-layout[5]. @@ -146,7 +153,7 @@ EXAMPLES and its subdirectories: + ------------ -$ git add Documentation/\\*.txt +$ git add Documentation/\*.txt ------------ + Note that the asterisk `\*` is quoted from the shell in this @@ -181,7 +188,7 @@ and type return, like this: What now> 1 ------------ -You also could say "s" or "sta" or "status" above as long as the +You also could say `s` or `sta` or `status` above as long as the choice is unique. The main command loop has 6 subcommands (plus help and quit). @@ -189,9 +196,9 @@ The main command loop has 6 subcommands (plus help and quit). status:: This shows the change between HEAD and index (i.e. what will be - committed if you say "git commit"), and between index and + committed if you say `git commit`), and between index and working tree files (i.e. what you could stage further before - "git commit" using "git-add") for each path. A sample output + `git commit` using `git add`) for each path. A sample output looks like this: + ------------ diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt index 8c7b7b0838..b786471dd8 100644 --- a/Documentation/git-blame.txt +++ b/Documentation/git-blame.txt @@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] 'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-p] [-w] [--incremental] [-L n,m] - [-S <revs-file>] [-M] [-C] [-C] [--since=<date>] + [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>] [<rev> | --contents <file> | --reverse <rev>] [--] <file> DESCRIPTION diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt index 0aeef24780..3f7835f4a7 100644 --- a/Documentation/git-check-ref-format.txt +++ b/Documentation/git-check-ref-format.txt @@ -43,7 +43,7 @@ imposes the following rules on how references are named: . They cannot contain a sequence `@{`. -- They cannot contain a `\\`. +. They cannot contain a `\\`. These rules make it easy for shell script based tools to parse reference names, pathname expansion by the shell when a reference name is used diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt index 288032c7b8..e6d364f53c 100644 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.txt @@ -311,8 +311,8 @@ change to the project. .... 'commit' SP <ref> LF mark? - ('author' SP <name> SP LT <email> GT SP <when> LF)? - 'committer' SP <name> SP LT <email> GT SP <when> LF + ('author' (SP <name>)? SP LT <email> GT SP <when> LF)? + 'committer' (SP <name>)? SP LT <email> GT SP <when> LF data ('from' SP <committish> LF)? ('merge' SP <committish> LF)? @@ -657,7 +657,7 @@ lightweight (non-annotated) tags see the `reset` command below. .... 'tag' SP <name> LF 'from' SP <committish> LF - 'tagger' SP <name> SP LT <email> GT SP <when> LF + 'tagger' (SP <name>)? SP LT <email> GT SP <when> LF data .... diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index 52c0538df5..ab1bf99fdb 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -165,12 +165,17 @@ If --porcelain is used, then each line of the output is of the form: <flag> \t <from>:<to> \t <summary> (<reason>) ------------------------------- +The status of up-to-date refs is shown only if --porcelain or --verbose +option is used. + flag:: - A single character indicating the status of the ref. This is - blank for a successfully pushed ref, `!` for a ref that was - rejected or failed to push, and '=' for a ref that was up to - date and did not need pushing (note that the status of up to - date refs is shown only when `git push` is running verbosely). + A single character indicating the status of the ref: +(space);; for a successfully pushed fast-forward; +`{plus}`;; for a successful forced update; +`-`;; for a successfully deleted ref; +`*`;; for a successfully pushed new ref; +`!`;; for a ref that was rejected or failed to push; and +`=`;; for a ref that was up to date and did not need pushing. summary:: For a successfully pushed ref, the summary shows the old and new diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt index 5afb1e7428..c21d19e573 100644 --- a/Documentation/git-rm.txt +++ b/Documentation/git-rm.txt @@ -12,13 +12,13 @@ SYNOPSIS DESCRIPTION ----------- Remove files from the index, or from the working tree and the index. -'git-rm' will not remove a file from just your working directory. -(There is no option to remove a file only from the work tree +`git rm` will not remove a file from just your working directory. +(There is no option to remove a file only from the working tree and yet keep it in the index; use `/bin/rm` if you want to do that.) The files being removed have to be identical to the tip of the branch, and no updates to their contents can be staged in the index, though that default behavior can be overridden with the `-f` option. -When '--cached' is given, the staged content has to +When `--cached` is given, the staged content has to match either the tip of the branch or the file on disk, allowing the file to be removed from just the index. @@ -64,7 +64,7 @@ OPTIONS -q:: --quiet:: - 'git-rm' normally outputs one line (in the form of an "rm" command) + `git rm` normally outputs one line (in the form of an `rm` command) for each file removed. This option suppresses that output. @@ -81,6 +81,58 @@ two directories `d` and `d2`, there is a difference between using `git rm \'d\*\'` and `git rm \'d/\*\'`, as the former will also remove all of directory `d2`. +REMOVING FILES THAT HAVE DISAPPEARED FROM THE FILESYSTEM +-------------------------------------------------------- +There is no option for `git rm` to remove from the index only +the paths that have disappeared from the filesystem. However, +depending on the use case, there are several ways that can be +done. + +Using "git commit -a" +~~~~~~~~~~~~~~~~~~~~~ +If you intend that your next commit should record all modifications +of tracked files in the working tree and record all removals of +files that have been removed from the working tree with `rm` +(as opposed to `git rm`), use `git commit -a`, as it will +automatically notice and record all removals. You can also have a +similar effect without committing by using `git add -u`. + +Using "git add -A" +~~~~~~~~~~~~~~~~~~ +When accepting a new code drop for a vendor branch, you probably +want to record both the removal of paths and additions of new paths +as well as modifications of existing paths. + +Typically you would first remove all tracked files from the working +tree using this command: + +---------------- +git ls-files -z | xargs -0 rm -f +---------------- + +and then "untar" the new code in the working tree. Alternately +you could "rsync" the changes into the working tree. + +After that, the easiest way to record all removals, additions, and +modifications in the working tree is: + +---------------- +git add -A +---------------- + +See linkgit:git-add[1]. + +Other ways +~~~~~~~~~~ +If all you really want to do is to remove from the index the files +that are no longer present in the working tree (perhaps because +your working tree is dirty so that you cannot use `git commit -a`), +use the following command: + +---------------- +git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached +---------------- + EXAMPLES -------- git rm Documentation/\\*.txt:: diff --git a/Documentation/git.txt b/Documentation/git.txt index 352c23019f..b6df39ba36 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,14 +43,16 @@ unreleased) version of git, that is available from 'master' branch of the `git.git` repository. Documentation for older releases are available here: -* link:v1.6.6/git.html[documentation for release 1.6.6] +* link:v1.6.6.1/git.html[documentation for release 1.6.6.1] * release notes for + link:RelNotes-1.6.6.1.txt[1.6.6.1], link:RelNotes-1.6.6.txt[1.6.6]. -* link:v1.6.5.7/git.html[documentation for release 1.6.5.7] +* link:v1.6.5.8/git.html[documentation for release 1.6.5.8] * release notes for + link:RelNotes-1.6.5.8.txt[1.6.5.8], link:RelNotes-1.6.5.7.txt[1.6.5.7], link:RelNotes-1.6.5.6.txt[1.6.5.6], link:RelNotes-1.6.5.5.txt[1.6.5.5], diff --git a/Documentation/pretty-options.txt b/Documentation/pretty-options.txt index bff94991b6..aa96caeab2 100644 --- a/Documentation/pretty-options.txt +++ b/Documentation/pretty-options.txt @@ -28,3 +28,11 @@ people using 80-column terminals. command to re-code the commit log message in the encoding preferred by the user. For non plumbing commands this defaults to UTF-8. + +--no-notes:: +--show-notes:: + Show the notes (see linkgit:git-notes[1]) that annotate the + commit, when showing the commit log message. This is the default + for `git log`, `git show` and `git whatchanged` commands when + there is no `--pretty`, `--format` nor `--oneline` option is + given on the command line. diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 1628d986fe..4e0adcade9 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.6.6 +DEF_VER=v1.6.6.1 LF=' ' @@ -828,6 +828,7 @@ ifeq ($(uname_O),Cygwin) endif ifeq ($(uname_S),FreeBSD) NEEDS_LIBICONV = YesPlease + OLD_ICONV = YesPlease NO_MEMMEM = YesPlease BASIC_CFLAGS += -I/usr/local/include BASIC_LDFLAGS += -L/usr/local/lib @@ -1 +1 @@ -Documentation/RelNotes-1.6.6.txt
\ No newline at end of file +Documentation/RelNotes-1.6.6.1.txt
\ No newline at end of file @@ -211,10 +211,33 @@ static const struct archiver *lookup_archiver(const char *name) return NULL; } +static int reject_entry(const unsigned char *sha1, const char *base, + int baselen, const char *filename, unsigned mode, + int stage, void *context) +{ + return -1; +} + +static int path_exists(struct tree *tree, const char *path) +{ + const char *pathspec[] = { path, NULL }; + + if (read_tree_recursive(tree, "", 0, 0, pathspec, reject_entry, NULL)) + return 1; + return 0; +} + static void parse_pathspec_arg(const char **pathspec, struct archiver_args *ar_args) { - ar_args->pathspec = get_pathspec("", pathspec); + ar_args->pathspec = pathspec = get_pathspec("", pathspec); + if (pathspec) { + while (*pathspec) { + if (!path_exists(ar_args->tree, *pathspec)) + die("path not found: %s", *pathspec); + pathspec++; + } + } } static void parse_treeish_arg(const char **argv, @@ -57,14 +57,8 @@ int decode_85(char *dst, const char *buffer, int len) de = de85[ch]; if (--de < 0) return error("invalid base85 alphabet %c", ch); - /* - * Detect overflow. The largest - * 5-letter possible is "|NsC0" to - * encode 0xffffffff, and "|NsC" gives - * 0x03030303 at this point (i.e. - * 0xffffffff = 0x03030303 * 85). - */ - if (0x03030303 < acc || + /* Detect overflow. */ + if (0xffffffff / 85 < acc || 0xffffffff - de < (acc *= 85)) return error("invalid base85 sequence %.5s", buffer-5); acc += de; @@ -84,8 +78,6 @@ int decode_85(char *dst, const char *buffer, int len) void encode_85(char *buf, const unsigned char *data, int bytes) { - prep_base85(); - say("encode 85"); while (bytes) { unsigned acc = 0; @@ -118,7 +110,7 @@ int main(int ac, char **av) int len = strlen(av[2]); encode_85(buf, av[2], len); if (len <= 26) len = len + 'A' - 1; - else len = len + 'a' - 26 + 1; + else len = len + 'a' - 26 - 1; printf("encoded: %c%s\n", len, buf); return 0; } @@ -956,7 +956,7 @@ int bisect_next_all(const char *prefix) { struct rev_info revs; struct commit_list *tried; - int reaches = 0, all = 0, nr; + int reaches = 0, all = 0, nr, steps; const unsigned char *bisect_rev; char bisect_rev_hex[41]; @@ -998,8 +998,10 @@ int bisect_next_all(const char *prefix) } nr = all - reaches - 1; - printf("Bisecting: %d revisions left to test after this " - "(roughly %d steps)\n", nr, estimate_bisect_steps(all)); + steps = estimate_bisect_steps(all); + printf("Bisecting: %d revision%s left to test after this " + "(roughly %d step%s)\n", nr, (nr == 1 ? "" : "s"), + steps, (steps == 1 ? "" : "s")); return bisect_checkout(bisect_rev_hex); } diff --git a/builtin-archive.c b/builtin-archive.c index 446d6bff30..faf4554d5e 100644 --- a/builtin-archive.c +++ b/builtin-archive.c @@ -67,7 +67,7 @@ static const char *format_from_name(const char *filename) return NULL; ext++; if (!strcasecmp(ext, "zip")) - return "zip"; + return "--format=zip"; return NULL; } @@ -81,7 +81,7 @@ int cmd_archive(int argc, const char **argv, const char *prefix) const char *exec = "git-upload-archive"; const char *output = NULL; const char *remote = NULL; - const char *format = NULL; + const char *format_option = NULL; struct option local_opts[] = { OPT_STRING('o', "output", &output, "file", "write the archive to this file"), @@ -89,33 +89,31 @@ int cmd_archive(int argc, const char **argv, const char *prefix) "retrieve the archive from remote repository <repo>"), OPT_STRING(0, "exec", &exec, "cmd", "path to the remote git-upload-archive command"), - OPT_STRING(0, "format", &format, "fmt", "archive format"), OPT_END() }; - char fmt_opt[32]; argc = parse_options(argc, argv, prefix, local_opts, NULL, PARSE_OPT_KEEP_ALL); if (output) { create_output_file(output); - if (!format) - format = format_from_name(output); + format_option = format_from_name(output); } - if (format) { - sprintf(fmt_opt, "--format=%s", format); - /* - * We have enough room in argv[] to muck it in place, - * because either --format and/or --output must have - * been given on the original command line if we get - * to this point, and parse_options() must have eaten - * it, i.e. we can add back one element to the array. - * But argv[] may contain "--"; we should make it the - * first option. - */ + /* + * We have enough room in argv[] to muck it in place, because + * --output must have been given on the original command line + * if we get to this point, and parse_options() must have eaten + * it, i.e. we can add back one element to the array. + * + * We add a fake --format option at the beginning, with the + * format inferred from our output filename. This way explicit + * --format options can override it, and the fake option is + * inserted before any "--" that might have been given. + */ + if (format_option) { memmove(argv + 2, argv + 1, sizeof(*argv) * argc); - argv[1] = fmt_opt; + argv[1] = format_option; argv[++argc] = NULL; } diff --git a/builtin-blame.c b/builtin-blame.c index 6408ec8ee6..10f7eacf6e 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -2433,7 +2433,7 @@ parse_done: if (top < 1) top = lno; bottom--; - if (lno < top) + if (lno < top || lno < bottom) die("file %s has only %lu lines", path, lno); ent = xcalloc(1, sizeof(*ent)); diff --git a/builtin-branch.c b/builtin-branch.c index c87e63b02d..ddc9f2dab7 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -638,10 +638,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix) rename_branch(head, argv[0], rename > 1); else if (rename && (argc == 2)) rename_branch(argv[0], argv[1], rename > 1); - else if (argc <= 2) + else if (argc <= 2) { + if (kinds != REF_LOCAL_BRANCH) + die("-a and -r options to 'git branch' do not make sense with a branch name"); create_branch(head, argv[0], (argc == 2) ? argv[1] : head, force_create, reflog, track); - else + } else usage_with_options(builtin_branch_usage, options); return 0; diff --git a/builtin-checkout.c b/builtin-checkout.c index 64f3a11ae1..67229fc216 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -167,7 +167,7 @@ static int checkout_merged(int pos, struct checkout *state) fill_mm(active_cache[pos+2]->sha1, &theirs); status = ll_merge(&result_buf, path, &ancestor, - &ours, "ours", &theirs, "theirs", 1); + &ours, "ours", &theirs, "theirs", 0); free(ancestor.ptr); free(ours.ptr); free(theirs.ptr); @@ -397,7 +397,7 @@ static int merge_working_tree(struct checkout_opts *opts, topts.initial_checkout = is_cache_unborn(); topts.update = 1; topts.merge = 1; - topts.gently = opts->merge; + topts.gently = opts->merge && old->commit; topts.verbose_update = !opts->quiet; topts.fn = twoway_merge; topts.dir = xcalloc(1, sizeof(*topts.dir)); @@ -422,7 +422,13 @@ static int merge_working_tree(struct checkout_opts *opts, struct merge_options o; if (!opts->merge) return 1; - parse_commit(old->commit); + + /* + * Without old->commit, the below is the same as + * the two-tree unpack we already tried and failed. + */ + if (!old->commit) + return 1; /* Do more real merge */ diff --git a/builtin-commit.c b/builtin-commit.c index f54772f74a..83b7c353ed 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -86,8 +86,8 @@ static int opt_parse_m(const struct option *opt, const char *arg, int unset) static struct option builtin_commit_options[] = { OPT__QUIET(&quiet), OPT__VERBOSE(&verbose), - OPT_GROUP("Commit message options"), + OPT_GROUP("Commit message options"), OPT_FILENAME('F', "file", &logfile, "read log from file"), OPT_STRING(0, "author", &force_author, "AUTHOR", "override author for commit"), OPT_CALLBACK('m', "message", &message, "MESSAGE", "specify commit message", opt_parse_m), @@ -97,6 +97,8 @@ static struct option builtin_commit_options[] = { OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"), OPT_FILENAME('t', "template", &template_file, "use specified template file"), OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"), + OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"), + /* end commit message options */ OPT_GROUP("Commit contents options"), OPT_BOOLEAN('a', "all", &all, "commit all changed files"), @@ -108,7 +110,7 @@ static struct option builtin_commit_options[] = { OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"), { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"), - OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"), + /* end commit contents options */ OPT_END() }; @@ -276,11 +278,13 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int * We still need to refresh the index here. */ if (!pathspec || !*pathspec) { - fd = hold_locked_index(&index_lock, 1); + fd = hold_locked_index(&index_lock, !is_status); refresh_cache(refresh_flags); - if (write_cache(fd, active_cache, active_nr) || - commit_locked_index(&index_lock)) - die("unable to write new_index file"); + if (0 <= fd) { + if (write_cache(fd, active_cache, active_nr) || + commit_locked_index(&index_lock)) + die("unable to write new_index file"); + } commit_style = COMMIT_AS_IS; return get_index_file(); } diff --git a/builtin-count-objects.c b/builtin-count-objects.c index 1b0b6c84ea..2bdd8ebde1 100644 --- a/builtin-count-objects.c +++ b/builtin-count-objects.c @@ -11,7 +11,7 @@ static void count_objects(DIR *d, char *path, int len, int verbose, unsigned long *loose, - unsigned long *loose_size, + off_t *loose_size, unsigned long *packed_loose, unsigned long *garbage) { @@ -77,7 +77,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) int len = strlen(objdir); char *path = xmalloc(len + 50); unsigned long loose = 0, packed = 0, packed_loose = 0, garbage = 0; - unsigned long loose_size = 0; + off_t loose_size = 0; struct option opts[] = { OPT__VERBOSE(&verbose), OPT_END(), @@ -103,7 +103,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) if (verbose) { struct packed_git *p; unsigned long num_pack = 0; - unsigned long size_pack = 0; + off_t size_pack = 0; if (!packed_git) prepare_packed_git(); for (p = packed_git; p; p = p->next) { @@ -116,15 +116,15 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) num_pack++; } printf("count: %lu\n", loose); - printf("size: %lu\n", loose_size / 1024); + printf("size: %lu\n", (unsigned long) (loose_size / 1024)); printf("in-pack: %lu\n", packed); printf("packs: %lu\n", num_pack); - printf("size-pack: %lu\n", size_pack / 1024); + printf("size-pack: %lu\n", (unsigned long) (size_pack / 1024)); printf("prune-packable: %lu\n", packed_loose); printf("garbage: %lu\n", garbage); } else printf("%lu objects, %lu kilobytes\n", - loose, loose_size / 1024); + loose, (unsigned long) (loose_size / 1024)); return 0; } diff --git a/builtin-fsck.c b/builtin-fsck.c index 0e5faae381..0929c7f245 100644 --- a/builtin-fsck.c +++ b/builtin-fsck.c @@ -578,7 +578,7 @@ static struct option fsck_opts[] = { OPT_BOOLEAN(0, "root", &show_root, "report root nodes"), OPT_BOOLEAN(0, "cache", &keep_cache_objects, "make index objects head nodes"), OPT_BOOLEAN(0, "reflogs", &include_reflogs, "make reflogs head nodes (default)"), - OPT_BOOLEAN(0, "full", &check_full, "also consider alternate objects"), + OPT_BOOLEAN(0, "full", &check_full, "also consider packs and alternate objects"), OPT_BOOLEAN(0, "strict", &check_strict, "enable more strict checking"), OPT_BOOLEAN(0, "lost-found", &write_lost_and_found, "write dangling objects in .git/lost-found"), diff --git a/builtin-grep.c b/builtin-grep.c index a5b6719a1a..c7d74fbb7f 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -191,8 +191,6 @@ static int grep_file(struct grep_opt *opt, const char *filename) error("'%s': %s", filename, strerror(errno)); return 0; } - if (!st.st_size) - return 0; /* empty file -- no grep hit */ if (!S_ISREG(st.st_mode)) return 0; sz = xsize_t(st.st_size); @@ -207,6 +205,7 @@ static int grep_file(struct grep_opt *opt, const char *filename) return 0; } close(i); + data[sz] = 0; if (opt->relative && opt->prefix_length) filename = quote_path_relative(filename, -1, &buf, opt->prefix); i = grep_buffer(opt, filename, data, sz); diff --git a/builtin-log.c b/builtin-log.c index 1766349550..2cb292fa72 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -58,6 +58,9 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix, usage(builtin_log_usage); argc = setup_revisions(argc, argv, rev, "HEAD"); + if (!rev->show_notes_given && !rev->pretty_given) + rev->show_notes = 1; + if (rev->diffopt.pickaxe || rev->diffopt.filter) rev->always_show_header = 0; if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) { diff --git a/builtin-remote.c b/builtin-remote.c index a5019397ff..c4945b8708 100644 --- a/builtin-remote.c +++ b/builtin-remote.c @@ -1238,13 +1238,11 @@ static int update(int argc, const char **argv) fetch_argv[fetch_argc++] = "--prune"; if (verbose) fetch_argv[fetch_argc++] = "-v"; - if (argc < 2) { + fetch_argv[fetch_argc++] = "--multiple"; + if (argc < 2) fetch_argv[fetch_argc++] = "default"; - } else { - fetch_argv[fetch_argc++] = "--multiple"; - for (i = 1; i < argc; i++) - fetch_argv[fetch_argc++] = argv[i]; - } + for (i = 1; i < argc; i++) + fetch_argv[fetch_argc++] = argv[i]; if (strcmp(fetch_argv[fetch_argc-1], "default") == 0) { git_config(get_remote_default, &default_defined); diff --git a/builtin-reset.c b/builtin-reset.c index 11d1c6e4d6..e4418bced2 100644 --- a/builtin-reset.c +++ b/builtin-reset.c @@ -286,10 +286,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix) if (reset_type == NONE) reset_type = MIXED; /* by default */ - if ((reset_type == HARD || reset_type == MERGE) - && !is_inside_work_tree()) - die("%s reset requires a work tree", - reset_type_names[reset_type]); + if (reset_type == HARD || reset_type == MERGE) + setup_work_tree(); /* Soft reset does not touch the index file nor the working tree * at all, but requires them in a good order. Other resets reset diff --git a/command-list.txt b/command-list.txt index cc5d48b385..95bf18cf06 100644 --- a/command-list.txt +++ b/command-list.txt @@ -49,6 +49,7 @@ git-grep mainporcelain common git-gui mainporcelain git-hash-object plumbingmanipulators git-help ancillaryinterrogators +git-http-backend synchingrepositories git-http-fetch synchelpers git-http-push synchelpers git-imap-send foreignscminterface @@ -224,7 +224,7 @@ int unregister_shallow(const unsigned char *sha1) if (pos < 0) return -1; if (pos + 1 < commit_graft_nr) - memcpy(commit_graft + pos, commit_graft + pos + 1, + memmove(commit_graft + pos, commit_graft + pos + 1, sizeof(struct commit_graft *) * (commit_graft_nr - pos - 1)); commit_graft_nr--; @@ -70,6 +70,7 @@ struct pretty_print_context const char *after_subject; enum date_mode date_mode; int need_8bit_cte; + int show_notes; struct reflog_walk_info *reflog_info; }; diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index fbfa5f25c1..1a762e88e7 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -142,11 +142,9 @@ __git_ps1 () elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then - git diff --no-ext-diff --ignore-submodules \ - --quiet --exit-code || w="*" + git diff --no-ext-diff --quiet --exit-code || w="*" if git rev-parse --quiet --verify HEAD >/dev/null; then - git diff-index --cached --quiet \ - --ignore-submodules HEAD -- || i="+" + git diff-index --cached --quiet HEAD -- || i="+" else i="#" fi @@ -573,6 +571,7 @@ __git_list_porcelain_commands () read-tree) : plumbing;; receive-pack) : plumbing;; reflog) : plumbing;; + remote-*) : transport;; repo-config) : deprecated;; rerere) : plumbing;; rev-list) : plumbing;; @@ -3776,11 +3776,13 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec, if (start_command(&child) != 0 || strbuf_read(&buf, child.out, 0) < 0 || finish_command(&child) != 0) { + close(child.out); strbuf_release(&buf); remove_tempfile(); error("error running textconv command '%s'", pgm); return NULL; } + close(child.out); remove_tempfile(); return strbuf_detach(&buf, outsize); diff --git a/fast-import.c b/fast-import.c index dd3c99d60d..60d0aa2bb4 100644 --- a/fast-import.c +++ b/fast-import.c @@ -19,8 +19,8 @@ Format of STDIN stream: new_commit ::= 'commit' sp ref_str lf mark? - ('author' sp name sp '<' email '>' sp when lf)? - 'committer' sp name sp '<' email '>' sp when lf + ('author' (sp name)? sp '<' email '>' sp when lf)? + 'committer' (sp name)? sp '<' email '>' sp when lf commit_msg ('from' sp committish lf)? ('merge' sp committish lf)* @@ -47,7 +47,7 @@ Format of STDIN stream: new_tag ::= 'tag' sp tag_str lf 'from' sp committish lf - ('tagger' sp name sp '<' email '>' sp when lf)? + ('tagger' (sp name)? sp '<' email '>' sp when lf)? tag_msg; tag_msg ::= data; @@ -2305,6 +2305,7 @@ static void parse_new_tag(void) struct tag *t; uintmax_t from_mark = 0; unsigned char sha1[20]; + enum object_type type; /* Obtain the new tag name from the rest of our command */ sp = strchr(command_buf.buf, ' ') + 1; @@ -2325,19 +2326,18 @@ static void parse_new_tag(void) s = lookup_branch(from); if (s) { hashcpy(sha1, s->sha1); + type = OBJ_COMMIT; } else if (*from == ':') { struct object_entry *oe; from_mark = strtoumax(from + 1, NULL, 10); oe = find_mark(from_mark); - if (oe->type != OBJ_COMMIT) - die("Mark :%" PRIuMAX " not a commit", from_mark); + type = oe->type; hashcpy(sha1, oe->sha1); } else if (!get_sha1(from, sha1)) { unsigned long size; char *buf; - buf = read_object_with_reference(sha1, - commit_type, &size, sha1); + buf = read_sha1_file(sha1, &type, &size); if (!buf || size < 46) die("Not a valid commit: %s", from); free(buf); @@ -2362,7 +2362,7 @@ static void parse_new_tag(void) "object %s\n" "type %s\n" "tag %s\n", - sha1_to_hex(sha1), commit_type, t->name); + sha1_to_hex(sha1), typename(type), t->name); if (tagger) strbuf_addf(&new_data, "tagger %s\n", tagger); diff --git a/git-gui/Makefile b/git-gui/Makefile index b3580e9e48..197b55edf3 100644 --- a/git-gui/Makefile +++ b/git-gui/Makefile @@ -7,7 +7,7 @@ all:: # TCL_PATH must be vaild for this to work. # -GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE +GIT-VERSION-FILE: FORCE @$(SHELL_PATH) ./GIT-VERSION-GEN -include GIT-VERSION-FILE @@ -270,7 +270,7 @@ TRACK_VARS = \ GITGUI_MACOSXAPP=$(GITGUI_MACOSXAPP) \ #end TRACK_VARS -GIT-GUI-VARS: .FORCE-GIT-GUI-VARS +GIT-GUI-VARS: FORCE @VARS='$(TRACK_VARS)'; \ if test x"$$VARS" != x"`cat $@ 2>/dev/null`" ; then \ echo 1>&2 " * new locations or Tcl/Tk interpreter"; \ @@ -340,5 +340,4 @@ ifdef GITGUI_WINDOWS_WRAPPER endif .PHONY: all install uninstall dist-version clean -.PHONY: .FORCE-GIT-VERSION-FILE -.PHONY: .FORCE-GIT-GUI-VARS +.PHONY: FORCE diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index 718277a651..1fb3cbfc78 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh @@ -1074,6 +1074,8 @@ if {[catch { set _prefix {} }] && [catch { + # beware that from the .git dir this sets _gitdir to . + # and _prefix to the empty string set _gitdir [git rev-parse --git-dir] set _prefix [git rev-parse --show-prefix] } err]} { @@ -1082,6 +1084,14 @@ if {[catch { choose_repository::pick set picked 1 } + +# we expand the _gitdir when it's just a single dot (i.e. when we're being +# run from the .git dir itself) lest the routines to find the worktree +# get confused +if {$_gitdir eq "."} { + set _gitdir [pwd] +} + if {![file isdirectory $_gitdir] && [is_Cygwin]} { catch {set _gitdir [exec cygpath --windows $_gitdir]} } @@ -1613,6 +1623,9 @@ proc merge_state {path new_state {head_info {}} {index_info {}}} { } elseif {$s0 ne {_} && [string index $state 0] eq {_} && $head_info eq {}} { set head_info $index_info + } elseif {$s0 eq {_} && [string index $state 0] ne {_}} { + set index_info $head_info + set head_info {} } set file_states($path) [list $s0$s1 $icon \ @@ -1941,7 +1954,7 @@ proc do_gitk {revs} { cd [file dirname [gitdir]] set env(GIT_DIR) [file tail [gitdir]] - eval exec $cmd $revs & + eval exec $cmd $revs "--" "--" & if {$old_GIT_DIR eq {}} { unset env(GIT_DIR) @@ -2543,12 +2556,14 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} { [list .mbar.commit entryconf [.mbar.commit index last] -state] .mbar.commit add command -label [mc "Unstage From Commit"] \ - -command do_unstage_selection + -command do_unstage_selection \ + -accelerator $M1T-U lappend disable_on_lock \ [list .mbar.commit entryconf [.mbar.commit index last] -state] .mbar.commit add command -label [mc "Revert Changes"] \ - -command do_revert_selection + -command do_revert_selection \ + -accelerator $M1T-J lappend disable_on_lock \ [list .mbar.commit entryconf [.mbar.commit index last] -state] @@ -3296,6 +3311,10 @@ unset gws bind $ui_comm <$M1B-Key-Return> {do_commit;break} bind $ui_comm <$M1B-Key-t> {do_add_selection;break} bind $ui_comm <$M1B-Key-T> {do_add_selection;break} +bind $ui_comm <$M1B-Key-u> {do_unstage_selection;break} +bind $ui_comm <$M1B-Key-U> {do_unstage_selection;break} +bind $ui_comm <$M1B-Key-j> {do_revert_selection;break} +bind $ui_comm <$M1B-Key-J> {do_revert_selection;break} bind $ui_comm <$M1B-Key-i> {do_add_all;break} bind $ui_comm <$M1B-Key-I> {do_add_all;break} bind $ui_comm <$M1B-Key-x> {tk_textCut %W;break} diff --git a/git-gui/lib/choose_repository.tcl b/git-gui/lib/choose_repository.tcl index 633cc572bb..3f8f3030fa 100644 --- a/git-gui/lib/choose_repository.tcl +++ b/git-gui/lib/choose_repository.tcl @@ -235,6 +235,8 @@ proc _get_recentrepos {} { foreach p [get_config gui.recentrepo] { if {[_is_git [file join $p .git]]} { lappend recent $p + } else { + _unset_recentrepo $p } } return [lsort $recent] @@ -243,6 +245,7 @@ proc _get_recentrepos {} { proc _unset_recentrepo {p} { regsub -all -- {([()\[\]{}\.^$+*?\\])} $p {\\\1} p git config --global --unset gui.recentrepo "^$p\$" + load_config 1 } proc _append_recentrepos {path} { @@ -261,6 +264,7 @@ proc _append_recentrepos {path} { lappend recent $path git config --global --add gui.recentrepo $path + load_config 1 while {[llength $recent] > 10} { _unset_recentrepo [lindex $recent 0] diff --git a/git-gui/lib/diff.tcl b/git-gui/lib/diff.tcl index bd5d189ed1..066755b864 100644 --- a/git-gui/lib/diff.tcl +++ b/git-gui/lib/diff.tcl @@ -664,6 +664,7 @@ proc apply_line {x y} { } set i_l $next_l } + set patch "$patch$pre_context" set patch "@@ -$hln,$n +$hln,[eval expr $n $sign 1] @@\n$patch" if {[catch { diff --git a/git-gui/lib/index.tcl b/git-gui/lib/index.tcl index d33896a0ce..0b58bd8876 100644 --- a/git-gui/lib/index.tcl +++ b/git-gui/lib/index.tcl @@ -14,29 +14,31 @@ proc _close_updateindex {fd after} { toplevel $w wm title $w [strcat "[appname] ([reponame]): " [mc "Index Error"]] wm geometry $w "+[winfo rootx .]+[winfo rooty .]" - pack [label $w.msg \ - -justify left \ - -anchor w \ - -text [strcat \ - [mc "Updating the Git index failed. A rescan will be automatically started to resynchronize git-gui."] \ - "\n\n$err"] \ - ] -anchor w - - frame $w.buttons - button $w.buttons.continue \ + set s [mc "Updating the Git index failed. A rescan will be automatically started to resynchronize git-gui."] + text $w.msg -yscrollcommand [list $w.vs set] \ + -width [string length $s] -relief flat \ + -borderwidth 0 -highlightthickness 0 \ + -background [$w cget -background] + $w.msg tag configure bold -font font_uibold -justify center + scrollbar $w.vs -command [list $w.msg yview] + $w.msg insert end $s bold \n\n$err {} + $w.msg configure -state disabled + + button $w.continue \ -text [mc "Continue"] \ -command [list destroy $w] - pack $w.buttons.continue -side right -padx 5 - button $w.buttons.unlock \ + button $w.unlock \ -text [mc "Unlock Index"] \ -command "destroy $w; _delete_indexlock" - pack $w.buttons.unlock -side right - pack $w.buttons -side bottom -fill x -pady 10 -padx 10 + grid $w.msg - $w.vs -sticky news + grid $w.unlock $w.continue - -sticky se -padx 2 -pady 2 + grid columnconfigure $w 0 -weight 1 + grid rowconfigure $w 0 -weight 1 wm protocol $w WM_DELETE_WINDOW update - bind $w.buttons.continue <Visibility> " + bind $w.continue <Visibility> " grab $w - focus $w.buttons.continue + focus %W " tkwait window $w diff --git a/git-merge-octopus.sh b/git-merge-octopus.sh index 825c52c243..615753c83c 100755 --- a/git-merge-octopus.sh +++ b/git-merge-octopus.sh @@ -44,9 +44,8 @@ esac # MRC is the current "merge reference commit" # MRT is the current "merge result tree" -MRC=$head MSG= PARENT="-p $head" +MRC=$(git rev-parse --verify -q $head) MRT=$(git write-tree) -CNT=1 ;# counting our head NON_FF_MERGE=0 OCTOPUS_FAILURE=0 for SHA1 in $remotes @@ -61,19 +60,17 @@ do exit 2 esac + eval pretty_name=\${GITHEAD_$SHA1:-$SHA1} common=$(git merge-base --all $SHA1 $MRC) || - die "Unable to find common commit with $SHA1" + die "Unable to find common commit with $pretty_name" case "$LF$common$LF" in *"$LF$SHA1$LF"*) - echo "Already up-to-date with $SHA1" + echo "Already up-to-date with $pretty_name" continue ;; esac - CNT=`expr $CNT + 1` - PARENT="$PARENT -p $SHA1" - if test "$common,$NON_FF_MERGE" = "$MRC,0" then # The first head being merged was a fast-forward. @@ -81,7 +78,7 @@ do # tree as the intermediate result of the merge. # We still need to count this as part of the parent set. - echo "Fast-forwarding to: $SHA1" + echo "Fast-forwarding to: $pretty_name" git read-tree -u -m $head $SHA1 || exit MRC=$SHA1 MRT=$(git write-tree) continue @@ -89,7 +86,7 @@ do NON_FF_MERGE=1 - echo "Trying simple merge with $SHA1" + echo "Trying simple merge with $pretty_name" git read-tree -u -m --aggressive $common $MRT $SHA1 || exit 2 next=$(git write-tree 2>/dev/null) if test $? -ne 0 diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index d52932878c..6ed57e2664 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -322,7 +322,7 @@ make_squash_message () { } peek_next_command () { - sed -n "1s/ .*$//p" < "$TODO" + sed -n -e "/^#/d" -e "/^$/d" -e "s/ .*//p" -e "q" < "$TODO" } do_next () { diff --git a/git-stash.sh b/git-stash.sh index f796c2fe24..3a0685f189 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -7,7 +7,7 @@ USAGE="list [<options>] or: $dashless drop [-q|--quiet] [<stash>] or: $dashless ( pop | apply ) [--index] [-q|--quiet] [<stash>] or: $dashless branch <branchname> [<stash>] - or: $dashless [save [-k|--keep-index] [-q|--quiet] [<message>]] + or: $dashless [save [--patch] [-k|--[no-]keep-index] [-q|--quiet] [<message>]] or: $dashless clear" SUBDIRECTORY_OK=Yes diff --git a/imap-send.c b/imap-send.c index de8114bac0..ea769a960a 100644 --- a/imap-send.c +++ b/imap-send.c @@ -1335,11 +1335,16 @@ static int git_imap_config(const char *key, const char *val, void *cb) if (strncmp(key, imap_key, sizeof imap_key - 1)) return 0; - if (!val) - return config_error_nonbool(key); - key += sizeof imap_key - 1; + /* check booleans first, and barf on others */ + if (!strcmp("sslverify", key)) + server.ssl_verify = git_config_bool(key, val); + else if (!strcmp("preformattedhtml", key)) + server.use_html = git_config_bool(key, val); + else if (!val) + return config_error_nonbool(key); + if (!strcmp("folder", key)) { imap_folder = xstrdup(val); } else if (!strcmp("host", key)) { @@ -1360,10 +1365,6 @@ static int git_imap_config(const char *key, const char *val, void *cb) server.port = git_config_int(key, val); else if (!strcmp("tunnel", key)) server.tunnel = xstrdup(val); - else if (!strcmp("sslverify", key)) - server.ssl_verify = git_config_bool(key, val); - else if (!strcmp("preformattedHTML", key)) - server.use_html = git_config_bool(key, val); return 0; } diff --git a/log-tree.c b/log-tree.c index 0fdf159f80..27afcf6972 100644 --- a/log-tree.c +++ b/log-tree.c @@ -284,6 +284,7 @@ void show_log(struct rev_info *opt) struct pretty_print_context ctx = {0}; opt->loginfo = NULL; + ctx.show_notes = opt->show_notes; if (!opt->verbose_header) { graph_show_commit(opt->graph); diff --git a/merge-recursive.c b/merge-recursive.c index dd4fbd0e6b..22a31ed5ff 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -200,14 +200,14 @@ struct tree *write_tree_from_memory(struct merge_options *o) if (unmerged_cache()) { int i; - output(o, 0, "There are unmerged index entries:"); + fprintf(stderr, "BUG: There are unmerged index entries:\n"); for (i = 0; i < active_nr; i++) { struct cache_entry *ce = active_cache[i]; if (ce_stage(ce)) - output(o, 0, "%d %.*s", ce_stage(ce), - (int)ce_namelen(ce), ce->name); + fprintf(stderr, "BUG: %d %.*s", ce_stage(ce), + (int)ce_namelen(ce), ce->name); } - return NULL; + die("Bug in merge-recursive.c"); } if (!active_cache_tree) @@ -394,17 +394,38 @@ int set_shared_perm(const char *path, int mode) const char *make_relative_path(const char *abs, const char *base) { static char buf[PATH_MAX + 1]; - int baselen; - if (!base) - return abs; - baselen = strlen(base); - if (prefixcmp(abs, base)) + int i = 0, j = 0; + + if (!base || !base[0]) return abs; - if (abs[baselen] == '/') - baselen++; - else if (base[baselen - 1] != '/') + while (base[i]) { + if (is_dir_sep(base[i])) { + if (!is_dir_sep(abs[j])) + return abs; + while (is_dir_sep(base[i])) + i++; + while (is_dir_sep(abs[j])) + j++; + continue; + } else if (abs[j] != base[i]) { + return abs; + } + i++; + j++; + } + if ( + /* "/foo" is a prefix of "/foo" */ + abs[j] && + /* "/foo" is not a prefix of "/foobar" */ + !is_dir_sep(base[i-1]) && !is_dir_sep(abs[j]) + ) return abs; - strcpy(buf, abs + baselen); + while (is_dir_sep(abs[j])) + j++; + if (!abs[j]) + strcpy(buf, "."); + else + strcpy(buf, abs + j); return buf; } @@ -1094,7 +1094,7 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit, if (fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body) strbuf_addch(sb, '\n'); - if (fmt != CMIT_FMT_ONELINE) + if (context->show_notes) get_commit_notes(commit, sb, encoding, NOTES_SHOW_HEADER | NOTES_INDENT); diff --git a/read-cache.c b/read-cache.c index 1bbaf1cffb..9033dd3ab9 100644 --- a/read-cache.c +++ b/read-cache.c @@ -1322,7 +1322,7 @@ int read_index_from(struct index_state *istate, const char *path) * extension name (4-byte) and section length * in 4-byte network byte order. */ - unsigned long extsize; + uint32_t extsize; memcpy(&extsize, (char *)mmap + src_offset + 4, 4); extsize = ntohl(extsize); if (read_index_extension(istate, diff --git a/remote-curl.c b/remote-curl.c index a331bae6c8..3edbf5717c 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -102,7 +102,7 @@ static struct discovery* discover_refs(const char *service) struct strbuf buffer = STRBUF_INIT; struct discovery *last = last_discovery; char *refs_url; - int http_ret, is_http = 0; + int http_ret, is_http = 0, proto_git_candidate = 1; if (last && !strcmp(service, last->service)) return last; @@ -121,6 +121,19 @@ static struct discovery* discover_refs(const char *service) init_walker(); http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE); + + /* try again with "plain" url (no ? or & appended) */ + if (http_ret != HTTP_OK) { + free(refs_url); + strbuf_reset(&buffer); + + proto_git_candidate = 0; + strbuf_addf(&buffer, "%s/info/refs", url); + refs_url = strbuf_detach(&buffer, NULL); + + http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE); + } + switch (http_ret) { case HTTP_OK: break; @@ -137,7 +150,8 @@ static struct discovery* discover_refs(const char *service) last->buf_alloc = strbuf_detach(&buffer, &last->len); last->buf = last->buf_alloc; - if (is_http && 5 <= last->len && last->buf[4] == '#') { + if (is_http && proto_git_candidate + && 5 <= last->len && last->buf[4] == '#') { /* smart HTTP response; validate that the service * pkt-line matches our request. */ @@ -480,7 +494,7 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads) strbuf_addf(&buf, "Content-Type: application/x-%s-request", svc); rpc->hdr_content_type = strbuf_detach(&buf, NULL); - strbuf_addf(&buf, "Accept: application/x-%s-response", svc); + strbuf_addf(&buf, "Accept: application/x-%s-result", svc); rpc->hdr_accept = strbuf_detach(&buf, NULL); while (!err) { diff --git a/revision.c b/revision.c index a8a3c3a4bd..34f9ab98d1 100644 --- a/revision.c +++ b/revision.c @@ -1161,13 +1161,22 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->verbose_header = 1; } else if (!strcmp(arg, "--pretty")) { revs->verbose_header = 1; + revs->pretty_given = 1; get_commit_format(arg+8, revs); } else if (!prefixcmp(arg, "--pretty=") || !prefixcmp(arg, "--format=")) { revs->verbose_header = 1; + revs->pretty_given = 1; get_commit_format(arg+9, revs); + } else if (!strcmp(arg, "--show-notes")) { + revs->show_notes = 1; + revs->show_notes_given = 1; + } else if (!strcmp(arg, "--no-notes")) { + revs->show_notes = 0; + revs->show_notes_given = 1; } else if (!strcmp(arg, "--oneline")) { revs->verbose_header = 1; get_commit_format("oneline", revs); + revs->pretty_given = 1; revs->abbrev_commit = 1; } else if (!strcmp(arg, "--graph")) { revs->topo_order = 1; diff --git a/revision.h b/revision.h index d368003159..a14deefc25 100644 --- a/revision.h +++ b/revision.h @@ -80,6 +80,9 @@ struct rev_info { /* Format info */ unsigned int shown_one:1, show_merge:1, + show_notes:1, + show_notes_given:1, + pretty_given:1, abbrev_commit:1, use_terminator:1, missing_newline:1, diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh index 238c2f1c08..ab55eda158 100755 --- a/t/t1200-tutorial.sh +++ b/t/t1200-tutorial.sh @@ -259,7 +259,7 @@ test_expect_success 'git repack' 'git repack' test_expect_success 'git prune-packed' 'git prune-packed' test_expect_success '-> only packed objects' ' git prune && # Remove conflict marked blobs - ! find .git/objects/[0-9a-f][0-9a-f] -type f + test $(find .git/objects/[0-9a-f][0-9a-f] -type f -print 2>/dev/null | wc -l) = 0 ' test_done diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh index 74e6443664..9df301211c 100755 --- a/t/t1501-worktree.sh +++ b/t/t1501-worktree.sh @@ -189,4 +189,10 @@ test_expect_success 'absolute pathspec should fail gracefully' ' ) ' +test_expect_success 'make_relative_path handles double slashes in GIT_DIR' ' + : > dummy_file + echo git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file && + git --git-dir="$(pwd)//repo.git" --work-tree="$(pwd)" add dummy_file +' + test_done diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh index 1e34f4836f..5d9604b815 100755 --- a/t/t3301-notes.sh +++ b/t/t3301-notes.sh @@ -147,4 +147,63 @@ test_expect_success 'show -m and -F notes' ' test_cmp expect-m-and-F output ' +cat >expect << EOF +commit 15023535574ded8b1a89052b32673f84cf9582b8 +tree e070e3af51011e47b183c33adf9736736a525709 +parent 1584215f1d29c65e99c6c6848626553fdd07fd75 +author A U Thor <author@example.com> 1112912173 -0700 +committer C O Mitter <committer@example.com> 1112912173 -0700 + + 4th +EOF +test_expect_success 'git log --pretty=raw does not show notes' ' + git log -1 --pretty=raw >output && + test_cmp expect output +' + +cat >>expect <<EOF + +Notes: + spam +$whitespace + xyzzy +$whitespace + foo + bar + baz +EOF +test_expect_success 'git log --show-notes' ' + git log -1 --pretty=raw --show-notes >output && + test_cmp expect output +' + +test_expect_success 'git log --no-notes' ' + git log -1 --no-notes >output && + ! grep spam output +' + +test_expect_success 'git format-patch does not show notes' ' + git format-patch -1 --stdout >output && + ! grep spam output +' + +test_expect_success 'git format-patch --show-notes does show notes' ' + git format-patch --show-notes -1 --stdout >output && + grep spam output +' + +for pretty in \ + "" --pretty --pretty=raw --pretty=short --pretty=medium \ + --pretty=full --pretty=fuller --pretty=format:%s --oneline +do + case "$pretty" in + "") p= not= negate="" ;; + ?*) p="$pretty" not=" not" negate="!" ;; + esac + test_expect_success "git show $pretty does$not show notes" ' + git show $p >output && + eval "$negate grep spam output" + ' +done + test_done diff --git a/t/t4019-diff-wserror.sh b/t/t4019-diff-wserror.sh index 3a3663fbcb..f6d1f1ebab 100755 --- a/t/t4019-diff-wserror.sh +++ b/t/t4019-diff-wserror.sh @@ -20,11 +20,27 @@ test_expect_success setup ' blue_grep='7;34m' ;# ESC [ 7 ; 3 4 m +printf "\033[%s" "$blue_grep" >check-grep +if (grep "$blue_grep" <check-grep | grep "$blue_grep") >/dev/null 2>&1 +then + grep_a=grep +elif (grep -a "$blue_grep" <check-grep | grep -a "$blue_grep") >/dev/null 2>&1 +then + grep_a='grep -a' +else + grep_a=grep ;# expected to fail... +fi +rm -f check-grep + +prepare_output () { + git diff --color >output + $grep_a "$blue_grep" output >error + $grep_a -v "$blue_grep" output >normal +} + test_expect_success default ' - git diff --color >output - grep "$blue_grep" output >error - grep -v "$blue_grep" output >normal + prepare_output grep Eight normal >/dev/null && grep HT error >/dev/null && @@ -37,9 +53,7 @@ test_expect_success default ' test_expect_success 'without -trail' ' git config core.whitespace -trail - git diff --color >output - grep "$blue_grep" output >error - grep -v "$blue_grep" output >normal + prepare_output grep Eight normal >/dev/null && grep HT error >/dev/null && @@ -53,9 +67,7 @@ test_expect_success 'without -trail (attribute)' ' git config --unset core.whitespace echo "F whitespace=-trail" >.gitattributes - git diff --color >output - grep "$blue_grep" output >error - grep -v "$blue_grep" output >normal + prepare_output grep Eight normal >/dev/null && grep HT error >/dev/null && @@ -69,9 +81,7 @@ test_expect_success 'without -space' ' rm -f .gitattributes git config core.whitespace -space - git diff --color >output - grep "$blue_grep" output >error - grep -v "$blue_grep" output >normal + prepare_output grep Eight normal >/dev/null && grep HT normal >/dev/null && @@ -85,9 +95,7 @@ test_expect_success 'without -space (attribute)' ' git config --unset core.whitespace echo "F whitespace=-space" >.gitattributes - git diff --color >output - grep "$blue_grep" output >error - grep -v "$blue_grep" output >normal + prepare_output grep Eight normal >/dev/null && grep HT normal >/dev/null && @@ -101,9 +109,7 @@ test_expect_success 'with indent-non-tab only' ' rm -f .gitattributes git config core.whitespace indent,-trailing,-space - git diff --color >output - grep "$blue_grep" output >error - grep -v "$blue_grep" output >normal + prepare_output grep Eight error >/dev/null && grep HT normal >/dev/null && @@ -117,9 +123,7 @@ test_expect_success 'with indent-non-tab only (attribute)' ' git config --unset core.whitespace echo "F whitespace=indent,-trailing,-space" >.gitattributes - git diff --color >output - grep "$blue_grep" output >error - grep -v "$blue_grep" output >normal + prepare_output grep Eight error >/dev/null && grep HT normal >/dev/null && @@ -133,9 +137,7 @@ test_expect_success 'with cr-at-eol' ' rm -f .gitattributes git config core.whitespace cr-at-eol - git diff --color >output - grep "$blue_grep" output >error - grep -v "$blue_grep" output >normal + prepare_output grep Eight normal >/dev/null && grep HT error >/dev/null && @@ -149,9 +151,7 @@ test_expect_success 'with cr-at-eol (attribute)' ' git config --unset core.whitespace echo "F whitespace=trailing,cr-at-eol" >.gitattributes - git diff --color >output - grep "$blue_grep" output >error - grep -v "$blue_grep" output >normal + prepare_output grep Eight normal >/dev/null && grep HT error >/dev/null && @@ -195,7 +195,7 @@ test_expect_success 'color new trailing blank lines' ' git add x && { echo a; echo; echo; echo; echo c; echo; echo; echo; echo; } >x && git diff --color x >output && - cnt=$(grep "${blue_grep}" output | wc -l) && + cnt=$($grep_a "${blue_grep}" output | wc -l) && test $cnt = 2 ' diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh index 0037f63d91..27bfba55bd 100755 --- a/t/t5000-tar-tree.sh +++ b/t/t5000-tar-tree.sh @@ -189,6 +189,16 @@ test_expect_success 'git archive --format=zip with --output' \ 'git archive --format=zip --output=d2.zip HEAD && test_cmp d.zip d2.zip' +test_expect_success 'git archive with --output, inferring format' ' + git archive --output=d3.zip HEAD && + test_cmp d.zip d3.zip +' + +test_expect_success 'git archive with --output, override inferred format' ' + git archive --format=tar --output=d4.zip HEAD && + test_cmp b.tar d4.zip +' + $UNZIP -v >/dev/null 2>&1 if [ $? -eq 127 ]; then say "Skipping ZIP tests, because unzip was not found" diff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh index 5858b868ed..d05a9138b4 100755 --- a/t/t5403-post-checkout-hook.sh +++ b/t/t5403-post-checkout-hook.sh @@ -7,19 +7,19 @@ test_description='Test the post-checkout hook.' . ./test-lib.sh test_expect_success setup ' - echo Data for commit0. >a && - echo Data for commit0. >b && - git update-index --add a && - git update-index --add b && - tree0=$(git write-tree) && - commit0=$(echo setup | git commit-tree $tree0) && - git update-ref refs/heads/master $commit0 && - git clone ./. clone1 && - git clone ./. clone2 && - GIT_DIR=clone2/.git git branch -a new2 && - echo Data for commit1. >clone2/b && - GIT_DIR=clone2/.git git add clone2/b && - GIT_DIR=clone2/.git git commit -m new2 + echo Data for commit0. >a && + echo Data for commit0. >b && + git update-index --add a && + git update-index --add b && + tree0=$(git write-tree) && + commit0=$(echo setup | git commit-tree $tree0) && + git update-ref refs/heads/master $commit0 && + git clone ./. clone1 && + git clone ./. clone2 && + GIT_DIR=clone2/.git git branch new2 && + echo Data for commit1. >clone2/b && + GIT_DIR=clone2/.git git add clone2/b && + GIT_DIR=clone2/.git git commit -m new2 ' for clone in 1 2; do diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index fd166d9de3..936fe0a1a6 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -419,6 +419,20 @@ test_expect_success 'update default (overridden, with funny whitespace)' ' ' +test_expect_success 'update (with remotes.default defined)' ' + + (cd one && + for b in $(git branch -r) + do + git branch -r -d $b || break + done && + git config remotes.default "drosophila" && + git remote update && + git branch -r > output && + test_cmp expect output) + +' + test_expect_success '"remote show" does not show symbolic refs' ' git clone one three && diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch.sh index c0505ecd7b..7faa31a299 100755 --- a/t/t5551-http-fetch.sh +++ b/t/t5551-http-fetch.sh @@ -38,7 +38,7 @@ cat >exp <<EOF > POST /smart/repo.git/git-upload-pack HTTP/1.1 > Accept-Encoding: deflate, gzip > Content-Type: application/x-git-upload-pack-request -> Accept: application/x-git-upload-pack-response +> Accept: application/x-git-upload-pack-result > Content-Length: xxx < HTTP/1.1 200 OK < Pragma: no-cache diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh index e85ff02c3e..b8cf2603a1 100755 --- a/t/t7102-reset.sh +++ b/t/t7102-reset.sh @@ -139,19 +139,19 @@ test_expect_success \ test_expect_success \ 'resetting to HEAD with no changes should succeed and do nothing' ' git reset --hard && - check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc && git reset --hard HEAD && - check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc && git reset --soft && - check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc && git reset --soft HEAD && - check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc && git reset --mixed && - check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc && git reset --mixed HEAD && - check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc && git reset && - check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc + check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc && git reset HEAD && check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc ' diff --git a/t/t7103-reset-bare.sh b/t/t7103-reset-bare.sh index 68041df5f4..afb55b3a46 100755 --- a/t/t7103-reset-bare.sh +++ b/t/t7103-reset-bare.sh @@ -29,6 +29,12 @@ test_expect_success 'soft reset is ok' ' (cd .git && git reset --soft) ' +test_expect_success 'hard reset works with GIT_WORK_TREE' ' + mkdir worktree && + GIT_WORK_TREE=$PWD/worktree GIT_DIR=$PWD/.git git reset --hard && + test_cmp file worktree/file +' + test_expect_success 'setup bare' ' git clone --bare . bare.git && cd bare.git diff --git a/t/t7201-co.sh b/t/t7201-co.sh index ebfd34df36..6442f710be 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -542,4 +542,61 @@ test_expect_success 'switch out of non-branch' ' ! grep "^Previous HEAD" error.log ' +( + echo "#!$SHELL_PATH" + cat <<\EOF +O=$1 A=$2 B=$3 +cat "$A" >.tmp +exec >"$A" +echo '<<<<<<< filfre-theirs' +cat "$B" +echo '||||||| filfre-common' +cat "$O" +echo '=======' +cat ".tmp" +echo '>>>>>>> filfre-ours' +rm -f .tmp +exit 1 +EOF +) >filfre.sh +chmod +x filfre.sh + +test_expect_success 'custom merge driver with checkout -m' ' + git reset --hard && + + git config merge.filfre.driver "./filfre.sh %O %A %B" && + git config merge.filfre.name "Feel-free merge driver" && + git config merge.filfre.recursive binary && + echo "arm merge=filfre" >.gitattributes && + + git checkout -b left && + echo neutral >arm && + git add arm .gitattributes && + test_tick && + git commit -m neutral && + git branch right && + + echo left >arm && + test_tick && + git commit -a -m left && + git checkout right && + + echo right >arm && + test_tick && + git commit -a -m right && + + test_must_fail git merge left && + ( + for t in filfre-common left right + do + grep $t arm || exit 1 + done + exit 0 + ) && + + mv arm expect && + git checkout -m arm && + test_cmp expect arm +' + test_done diff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh index 01e5415e94..2746169514 100755 --- a/t/t7602-merge-octopus-many.sh +++ b/t/t7602-merge-octopus-many.sh @@ -49,4 +49,55 @@ test_expect_success 'merge c1 with c2, c3, c4, ... c29' ' done ' +cat >expected <<\EOF +Trying simple merge with c2 +Trying simple merge with c3 +Trying simple merge with c4 +Merge made by octopus. + c2.c | 1 + + c3.c | 1 + + c4.c | 1 + + 3 files changed, 3 insertions(+), 0 deletions(-) + create mode 100644 c2.c + create mode 100644 c3.c + create mode 100644 c4.c +EOF + +test_expect_success 'merge output uses pretty names' ' + git reset --hard c1 && + git merge c2 c3 c4 >actual && + test_cmp actual expected +' + +cat >expected <<\EOF +Already up-to-date with c4 +Trying simple merge with c5 +Merge made by octopus. + c5.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + create mode 100644 c5.c +EOF + +test_expect_success 'merge up-to-date output uses pretty names' ' + git merge c4 c5 >actual && + test_cmp actual expected +' + +cat >expected <<\EOF +Fast-forwarding to: c1 +Trying simple merge with c2 +Merge made by octopus. + c1.c | 1 + + c2.c | 1 + + 2 files changed, 2 insertions(+), 0 deletions(-) + create mode 100644 c1.c + create mode 100644 c2.c +EOF + +test_expect_success 'merge fast-forward output uses pretty names' ' + git reset --hard c0 && + git merge c1 c2 >actual && + test_cmp actual expected +' + test_done diff --git a/t/t8003-blame.sh b/t/t8003-blame.sh index ad834f200a..4a8db74f7e 100755 --- a/t/t8003-blame.sh +++ b/t/t8003-blame.sh @@ -157,4 +157,12 @@ EOF git --no-pager blame $COMMIT -- uno >/dev/null ' +test_expect_success 'blame -L with invalid start' ' + test_must_fail git blame -L5 tres 2>&1 | grep "has only 2 lines" +' + +test_expect_success 'blame -L with invalid end' ' + git blame -L1,5 tres 2>&1 | grep "has only 2 lines" +' + test_done diff --git a/transport.c b/transport.c index 7362ec09b2..42b2c59a7b 100644 --- a/transport.c +++ b/transport.c @@ -143,7 +143,7 @@ static const char *rsync_url(const char *url) static struct ref *get_refs_via_rsync(struct transport *transport, int for_push) { struct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT; - struct ref dummy, *tail = &dummy; + struct ref dummy = {0}, *tail = &dummy; struct child_process rsync; const char *args[5]; int temp_dir_len; |