From 844c11ae259bd33b971b9ca389b3f9619427e9a8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 9 Apr 2007 21:13:29 -0700 Subject: diff-lib: use ce_mode_from_stat() rather than messing with modes manually The diff helpers used to do the magic mode canonicalization and all the other special mode handling by hand ("trust executable bit" and "has symlink support" handling). That's bogus. Use "ce_mode_from_stat()" that does this all for us. This is also going to be required when we add support for links to other git repositories. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- diff-lib.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index 5c5b05bfe3..c6d127346a 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -357,7 +357,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed) continue; } else - dpath->mode = canon_mode(st.st_mode); + dpath->mode = ntohl(ce_mode_from_stat(ce, st.st_mode)); while (i < entries) { struct cache_entry *nce = active_cache[i]; @@ -374,8 +374,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed) int mode = ntohl(nce->ce_mode); num_compare_stages++; hashcpy(dpath->parent[stage-2].sha1, nce->sha1); - dpath->parent[stage-2].mode = - canon_mode(mode); + dpath->parent[stage-2].mode = ntohl(ce_mode_from_stat(nce, mode)); dpath->parent[stage-2].status = DIFF_STATUS_MODIFIED; } @@ -424,15 +423,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed) if (!changed && !revs->diffopt.find_copies_harder) continue; oldmode = ntohl(ce->ce_mode); - - newmode = canon_mode(st.st_mode); - if (!trust_executable_bit && - S_ISREG(newmode) && S_ISREG(oldmode) && - ((newmode ^ oldmode) == 0111)) - newmode = oldmode; - else if (!has_symlinks && - S_ISREG(newmode) && S_ISLNK(oldmode)) - newmode = oldmode; + newmode = ntohl(ce_mode_from_stat(ce, st.st_mode)); diff_change(&revs->diffopt, oldmode, newmode, ce->sha1, (changed ? null_sha1 : ce->sha1), ce->name, NULL); -- cgit v1.3 From 1ad029b6a1e2fb0254667a2bea8d1ee180cc6ac7 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 13 Apr 2007 03:23:20 -0700 Subject: Do not default to --no-index when given two directories. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-diff -- a/ b/ always defaulted to --no-index, primarily because the function is_in_index() was implemented quite incorrectly. Noticed by Patrick Maaß and Simon Schubert independently, initial patch was provided by Patrick but I fixed it differently. Signed-off-by: Junio C Hamano --- diff-lib.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index 5c5b05bfe3..7531e20c78 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -142,18 +142,34 @@ static int queue_diff(struct diff_options *o, } } +/* + * Does the path name a blob in the working tree, or a directory + * in the working tree? + */ static int is_in_index(const char *path) { - int len = strlen(path); - int pos = cache_name_pos(path, len); - char c; - - if (pos < 0) - return 0; - if (strncmp(active_cache[pos]->name, path, len)) - return 0; - c = active_cache[pos]->name[len]; - return c == '\0' || c == '/'; + int len, pos; + struct cache_entry *ce; + + len = strlen(path); + while (path[len-1] == '/') + len--; + if (!len) + return 1; /* "." */ + pos = cache_name_pos(path, len); + if (0 <= pos) + return 1; + pos = -1 - pos; + while (pos < active_nr) { + ce = active_cache[pos++]; + if (ce_namelen(ce) <= len || + strncmp(ce->name, path, len) || + (ce->name[len] > '/')) + break; /* path cannot be a prefix */ + if (ce->name[len] == '/') + return 1; + } + return 0; } static int handle_diff_files_args(struct rev_info *revs, -- cgit v1.3 From a6080a0a44d5ead84db3dabbbc80e82df838533d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 7 Jun 2007 00:04:01 -0700 Subject: War on whitespace This uses "git-apply --whitespace=strip" to fix whitespace errors that have crept in to our source files over time. There are a few files that need to have trailing whitespaces (most notably, test vectors). The results still passes the test, and build result in Documentation/ area is unchanged. Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.5.0.4.txt | 2 - Documentation/RelNotes-1.5.0.5.txt | 2 - Documentation/RelNotes-1.5.0.6.txt | 1 - Documentation/RelNotes-1.5.1.3.txt | 1 - Documentation/SubmittingPatches | 14 +- Documentation/asciidoc.conf | 2 - Documentation/config.txt | 2 - Documentation/core-tutorial.txt | 46 +- Documentation/diff-format.txt | 21 +- Documentation/diff-options.txt | 4 +- Documentation/diffcore.txt | 3 +- Documentation/docbook-xsl.css | 572 ++++++++++----------- Documentation/fetch-options.txt | 1 - Documentation/git-add.txt | 1 - Documentation/git-am.txt | 1 - Documentation/git-apply.txt | 1 - Documentation/git-archimport.txt | 45 +- Documentation/git-bisect.txt | 3 +- Documentation/git-branch.txt | 1 - Documentation/git-cat-file.txt | 1 - Documentation/git-check-attr.txt | 1 - Documentation/git-checkout-index.txt | 1 - Documentation/git-checkout.txt | 1 - Documentation/git-cherry-pick.txt | 1 - Documentation/git-cherry.txt | 1 - Documentation/git-clone.txt | 1 - Documentation/git-commit-tree.txt | 3 +- Documentation/git-config.txt | 1 - Documentation/git-convert-objects.txt | 1 - Documentation/git-count-objects.txt | 1 - Documentation/git-cvsexportcommit.txt | 15 +- Documentation/git-cvsimport.txt | 13 +- Documentation/git-daemon.txt | 1 - Documentation/git-describe.txt | 1 - Documentation/git-diff-files.txt | 3 +- Documentation/git-diff-index.txt | 3 +- Documentation/git-diff-tree.txt | 1 - Documentation/git-diff.txt | 1 - Documentation/git-fast-import.txt | 1 - Documentation/git-fmt-merge-msg.txt | 1 - Documentation/git-format-patch.txt | 1 - Documentation/git-fsck.txt | 1 - Documentation/git-get-tar-commit-id.txt | 1 - Documentation/git-grep.txt | 1 - Documentation/git-hash-object.txt | 3 +- Documentation/git-http-fetch.txt | 1 - Documentation/git-http-push.txt | 2 +- Documentation/git-index-pack.txt | 1 - Documentation/git-init-db.txt | 1 - Documentation/git-init.txt | 1 - Documentation/git-instaweb.txt | 1 - Documentation/git-local-fetch.txt | 1 - Documentation/git-log.txt | 1 - Documentation/git-ls-files.txt | 1 - Documentation/git-ls-remote.txt | 1 - Documentation/git-ls-tree.txt | 1 - Documentation/git-mailinfo.txt | 1 - Documentation/git-mailsplit.txt | 1 - Documentation/git-merge-base.txt | 1 - Documentation/git-merge-index.txt | 3 +- Documentation/git-merge-one-file.txt | 1 - Documentation/git-merge-tree.txt | 1 - Documentation/git-merge.txt | 2 +- Documentation/git-mergetool.txt | 1 - Documentation/git-mktag.txt | 1 - Documentation/git-mktree.txt | 1 - Documentation/git-mv.txt | 1 - Documentation/git-name-rev.txt | 1 - Documentation/git-p4import.txt | 1 - Documentation/git-pack-objects.txt | 1 - Documentation/git-pack-redundant.txt | 3 +- Documentation/git-patch-id.txt | 1 - Documentation/git-peek-remote.txt | 1 - Documentation/git-prune-packed.txt | 1 - Documentation/git-prune.txt | 1 - Documentation/git-pull.txt | 1 - Documentation/git-push.txt | 1 - Documentation/git-quiltimport.txt | 1 - Documentation/git-read-tree.txt | 1 - Documentation/git-rebase.txt | 1 - Documentation/git-reflog.txt | 1 - Documentation/git-relink.txt | 1 - Documentation/git-remote.txt | 1 - Documentation/git-repack.txt | 1 - Documentation/git-request-pull.txt | 1 - Documentation/git-rev-parse.txt | 1 - Documentation/git-revert.txt | 1 - Documentation/git-rm.txt | 1 - Documentation/git-runstatus.txt | 1 - Documentation/git-send-email.txt | 3 +- Documentation/git-sh-setup.txt | 1 - Documentation/git-shell.txt | 1 - Documentation/git-shortlog.txt | 1 - Documentation/git-show-index.txt | 1 - Documentation/git-show.txt | 1 - Documentation/git-ssh-fetch.txt | 1 - Documentation/git-ssh-upload.txt | 1 - Documentation/git-status.txt | 1 - Documentation/git-stripspace.txt | 1 - Documentation/git-svnimport.txt | 1 - Documentation/git-tar-tree.txt | 1 - Documentation/git-unpack-file.txt | 1 - Documentation/git-unpack-objects.txt | 1 - Documentation/git-update-index.txt | 9 +- Documentation/git-update-server-info.txt | 1 - Documentation/git-var.txt | 1 - Documentation/git-verify-pack.txt | 1 - Documentation/git-verify-tag.txt | 1 - Documentation/git-whatchanged.txt | 1 - Documentation/git-write-tree.txt | 1 - Documentation/git.txt | 1 - Documentation/gitk.txt | 1 - Documentation/howto/rebase-and-edit.txt | 20 +- .../howto/rebase-from-internal-branch.txt | 12 +- Documentation/howto/rebuild-from-update-hook.txt | 1 - Documentation/howto/revert-branch-rebase.txt | 2 +- Documentation/howto/separating-topic-branches.txt | 13 +- Documentation/howto/use-git-daemon.txt | 1 - Documentation/merge-options.txt | 1 - Documentation/pretty-formats.txt | 1 - Documentation/pretty-options.txt | 1 - Documentation/pull-fetch-param.txt | 2 +- Documentation/repository-layout.txt | 1 - Documentation/technical/pack-format.txt | 8 +- Documentation/user-manual.txt | 38 +- GIT-VERSION-GEN | 2 - INSTALL | 3 +- arm/sha1.c | 4 +- arm/sha1_arm.S | 1 - builtin-annotate.c | 1 - builtin-diff-index.c | 2 +- builtin-fmt-merge-msg.c | 1 - builtin-fsck.c | 4 +- builtin-ls-files.c | 2 +- builtin-name-rev.c | 1 - builtin-pack-objects.c | 2 +- builtin-rerere.c | 1 - builtin-shortlog.c | 1 - cache.h | 2 +- commit.c | 14 +- commit.h | 2 +- compat/mmap.c | 1 - config.c | 3 +- config.mak.in | 1 - connect.c | 2 +- contrib/README | 1 - contrib/blameview/README | 1 - contrib/gitview/gitview | 2 - contrib/hooks/post-receive-email | 2 +- contrib/remotes2config.sh | 2 - convert-objects.c | 2 +- copy.c | 1 - ctype.c | 1 - daemon.c | 4 +- date.c | 10 +- diff-lib.c | 2 +- diff.c | 4 +- diffcore-pickaxe.c | 2 +- entry.c | 2 +- environment.c | 2 - fetch-pack.c | 2 +- fetch.c | 4 +- git-archimport.perl | 175 ++++--- git-checkout.sh | 4 +- git-clone.sh | 5 +- git-commit.sh | 2 +- git-cvsexportcommit.perl | 2 +- git-cvsimport.perl | 12 +- git-gui/GIT-VERSION-GEN | 2 - git-gui/lib/class.tcl | 1 - git-merge-one-file.sh | 2 +- git-p4import.py | 1 - git-svnimport.perl | 4 +- git-tag.sh | 5 +- git-verify-tag.sh | 1 - git.spec.in | 2 +- gitk | 2 +- gitweb/README | 1 - help.c | 2 - http-fetch.c | 2 +- http-push.c | 2 +- http.c | 2 +- imap-send.c | 2 +- local-fetch.c | 8 +- lockfile.c | 1 - mailmap.c | 1 - match-trees.c | 1 - merge-index.c | 2 +- mktag.c | 2 +- mozilla-sha1/sha1.c | 19 +- mozilla-sha1/sha1.h | 18 +- object-refs.c | 2 - object.h | 2 +- pack-redundant.c | 4 +- patch-id.c | 2 +- path-list.c | 1 - perl/Makefile | 1 - pkt-line.c | 2 +- ppc/sha1.c | 2 +- read-cache.c | 10 +- rsh.h | 2 +- setup.c | 4 +- sha1_file.c | 8 +- shallow.c | 1 - ssh-upload.c | 10 +- strbuf.c | 1 - t/Makefile | 1 - t/lib-read-tree-m-3way.sh | 2 +- t/t0000-basic.sh | 2 +- t/t1200-tutorial.sh | 1 - t/t1300-repo-config.sh | 1 - t/t2000-checkout-cache-clash.sh | 2 - t/t2001-checkout-cache-clash.sh | 1 - t/t3030-merge-recursive.sh | 1 - t/t3403-rebase-skip.sh | 1 - t/t4006-diff-mode.sh | 1 - t/t4100-apply-stat.sh | 1 - t/t4110-apply-scan.sh | 1 - t/t4112-apply-renames.sh | 16 +- t/t4118-apply-empty-context.sh | 1 - t/t4119-apply-config.sh | 2 +- t/t4121-apply-diffs.sh | 1 - t/t4122-apply-symlink-inside.sh | 1 - t/t4200-rerere.sh | 2 - t/t5400-send-pack.sh | 2 +- t/t5520-pull.sh | 1 - t/t5710-info-alternate.sh | 1 - t/t6000lib.sh | 16 +- t/t6002-rev-list-bisect.sh | 8 +- t/t6021-merge-criss-cross.sh | 2 +- t/t6023-merge-file.sh | 1 - t/t6030-bisect-porcelain.sh | 1 - t/t6101-rev-parse-parents.sh | 1 - t/t9107-git-svn-migrate.sh | 1 - t/t9111/svnsync.dump | 2 - t/test-lib.sh | 2 +- templates/hooks--commit-msg | 1 - templates/hooks--post-receive | 1 - templates/hooks--pre-applypatch | 1 - templates/hooks--pre-commit | 1 - tree-walk.c | 1 - upload-pack.c | 2 +- var.c | 4 +- xdiff-interface.c | 2 - xdiff/xdiff.h | 1 - xdiff/xdiffi.c | 1 - xdiff/xdiffi.h | 1 - xdiff/xemit.c | 1 - xdiff/xemit.h | 1 - xdiff/xinclude.h | 1 - xdiff/xmacros.h | 1 - xdiff/xprepare.c | 1 - xdiff/xprepare.h | 1 - xdiff/xtypes.h | 1 - xdiff/xutils.c | 1 - xdiff/xutils.h | 1 - 256 files changed, 645 insertions(+), 852 deletions(-) (limited to 'diff-lib.c') diff --git a/Documentation/RelNotes-1.5.0.4.txt b/Documentation/RelNotes-1.5.0.4.txt index b727a8d1e5..feefa5dfd4 100644 --- a/Documentation/RelNotes-1.5.0.4.txt +++ b/Documentation/RelNotes-1.5.0.4.txt @@ -20,5 +20,3 @@ Fixes since v1.5.0.3 * Documentation updates * User manual updates - - diff --git a/Documentation/RelNotes-1.5.0.5.txt b/Documentation/RelNotes-1.5.0.5.txt index aa86149d4f..eeec3d73d0 100644 --- a/Documentation/RelNotes-1.5.0.5.txt +++ b/Documentation/RelNotes-1.5.0.5.txt @@ -24,5 +24,3 @@ Fixes since v1.5.0.3 * Documentation updates * User manual updates - - diff --git a/Documentation/RelNotes-1.5.0.6.txt b/Documentation/RelNotes-1.5.0.6.txt index e15447ffdb..c02015ad5f 100644 --- a/Documentation/RelNotes-1.5.0.6.txt +++ b/Documentation/RelNotes-1.5.0.6.txt @@ -19,4 +19,3 @@ Fixes since v1.5.0.5 - user-manual has better cross references. - gitweb installation/deployment procedure is now documented. - diff --git a/Documentation/RelNotes-1.5.1.3.txt b/Documentation/RelNotes-1.5.1.3.txt index 2ddeabd029..876408b65a 100644 --- a/Documentation/RelNotes-1.5.1.3.txt +++ b/Documentation/RelNotes-1.5.1.3.txt @@ -43,4 +43,3 @@ Fixes since v1.5.1.2 description was given by the caller. Also contains various documentation updates. - diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index b9baa1d3b4..01354c2bb5 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -296,15 +296,15 @@ diff --git a/pico/pico.c b/pico/pico.c --- a/pico/pico.c +++ b/pico/pico.c @@ -219,7 +219,9 @@ PICO *pm; - switch(pico_all_done){ /* prepare for/handle final events */ - case COMP_EXIT : /* already confirmed */ - packheader(); + switch(pico_all_done){ /* prepare for/handle final events */ + case COMP_EXIT : /* already confirmed */ + packheader(); +#if 0 - stripwhitespace(); + stripwhitespace(); +#endif - c |= COMP_EXIT; - break; - + c |= COMP_EXIT; + break; + (Daniel Barkalow) diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf index 60e15ba349..99302c5beb 100644 --- a/Documentation/asciidoc.conf +++ b/Documentation/asciidoc.conf @@ -54,5 +54,3 @@ ifdef::backend-xhtml11[] [gitlink-inlinemacro] {target}{0?({0})} endif::backend-xhtml11[] - - diff --git a/Documentation/config.txt b/Documentation/config.txt index 5868d587a9..de408b6571 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -682,5 +682,3 @@ receive.denyNonFastForwards:: transfer.unpackLimit:: When `fetch.unpackLimit` or `receive.unpackLimit` are not set, the value of this variable is used instead. - - diff --git a/Documentation/core-tutorial.txt b/Documentation/core-tutorial.txt index 6b9b9ad7d1..4fb6f4143c 100644 --- a/Documentation/core-tutorial.txt +++ b/Documentation/core-tutorial.txt @@ -9,11 +9,11 @@ repository, mainly because being hands-on and using explicit examples is often the best way of explaining what is going on. In normal life, most people wouldn't use the "core" git programs -directly, but rather script around them to make them more palatable. +directly, but rather script around them to make them more palatable. Understanding the core git stuff may help some people get those scripts done, though, and it may also be instructive in helping people understand what it is that the higher-level helper scripts are actually -doing. +doing. The core git is often called "plumbing", with the prettier user interfaces on top of it called "porcelain". You may not want to use the @@ -41,7 +41,7 @@ Creating a new git repository couldn't be easier: all git repositories start out empty, and the only thing you need to do is find yourself a subdirectory that you want to use as a working tree - either an empty one for a totally new project, or an existing working tree that you want -to import into git. +to import into git. For our first example, we're going to start a totally new repository from scratch, with no pre-existing files, and we'll call it `git-tutorial`. @@ -169,7 +169,7 @@ $ ls .git/objects/??/* and see two files: ---------------- -.git/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238 +.git/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238 .git/objects/f2/4c74a2e500f5ee1332c86b94199f52b1d1d962 ---------------- @@ -220,7 +220,7 @@ you have not actually really "checked in" your files into git so far, you've only *told* git about them. However, since git knows about them, you can now start using some of the -most basic git commands to manipulate the files or look at their status. +most basic git commands to manipulate the files or look at their status. In particular, let's not even check in the two files into git yet, we'll start off by adding another line to `hello` first: @@ -350,7 +350,7 @@ Making a change Remember how we did the `git-update-index` on file `hello` and then we changed `hello` afterward, and could compare the new state of `hello` with the -state we saved in the index file? +state we saved in the index file? Further, remember how I said that `git-write-tree` writes the contents of the *index* file to the tree, and thus what we just committed was in @@ -370,7 +370,7 @@ file and the working tree, `git-diff-index` shows the differences between a committed *tree* and either the index file or the working tree. In other words, `git-diff-index` wants a tree to be diffed against, and before we did the commit, we couldn't do that, because we -didn't have anything to diff against. +didn't have anything to diff against. But now we can do @@ -379,7 +379,7 @@ $ git-diff-index -p HEAD ---------------- (where `-p` has the same meaning as it did in `git-diff-files`), and it -will show us the same difference, but for a totally different reason. +will show us the same difference, but for a totally different reason. Now we're comparing the working tree not against the index file, but against the tree we just wrote. It just so happens that those two are obviously the same, so we get the same result. @@ -398,7 +398,7 @@ working tree, but when given the `\--cached` flag, it is told to instead compare against just the index cache contents, and ignore the current working tree state entirely. Since we just wrote the index file to HEAD, doing `git-diff-index \--cached -p HEAD` should thus return -an empty set of differences, and that's exactly what it does. +an empty set of differences, and that's exactly what it does. [NOTE] ================ @@ -549,7 +549,7 @@ $ git-whatchanged -p --root ---------------- and you will see exactly what has changed in the repository over its -short history. +short history. [NOTE] The `\--root` flag is a flag to `git-diff-tree` to tell it to @@ -637,7 +637,7 @@ So the mental model of "the git information is always tied directly to the working tree that it describes" may not be technically 100% accurate, but it's a good model for all normal use. -This has two implications: +This has two implications: - if you grow bored with the tutorial repository you created (or you've made a mistake and want to start all over), you can just do simple @@ -705,7 +705,7 @@ Many (most?) public remote repositories will not contain any of the checked out files or even an index file, and will *only* contain the actual core git files. Such a repository usually doesn't even have the `.git` subdirectory, but has all the git files directly in the -repository. +repository. To create your own local live copy of such a "raw" git repository, you'd first create your own subdirectory for the project, and then copy the @@ -718,7 +718,7 @@ $ cd my-git $ rsync -rL rsync://rsync.kernel.org/pub/scm/git/git.git/ .git ---------------- -followed by +followed by ---------------- $ git-read-tree HEAD @@ -738,7 +738,7 @@ up-to-date (so that you don't have to refresh it afterward), and the `-a` flag means "check out all files" (if you have a stale copy or an older version of a checked out tree you may also need to add the `-f` flag first, to tell git-checkout-index to *force* overwriting of any old -files). +files). Again, this can all be simplified with @@ -751,7 +751,7 @@ $ git checkout which will end up doing all of the above for you. You have now successfully copied somebody else's (mine) remote -repository, and checked it out. +repository, and checked it out. Creating a new branch @@ -760,14 +760,14 @@ Creating a new branch Branches in git are really nothing more than pointers into the git object database from within the `.git/refs/` subdirectory, and as we already discussed, the `HEAD` branch is nothing but a symlink to one of -these object pointers. +these object pointers. You can at any time create a new branch by just picking an arbitrary point in the project history, and just writing the SHA1 name of that object into a file under `.git/refs/heads/`. You can use any filename you want (and indeed, subdirectories), but the convention is that the "normal" branch is called `master`. That's just a convention, though, -and nothing enforces it. +and nothing enforces it. To show that as an example, let's go back to the git-tutorial repository we used earlier, and create a branch in it. You do that by simply just @@ -778,7 +778,7 @@ $ git checkout -b mybranch ------------ will create a new branch based at the current `HEAD` position, and switch -to it. +to it. [NOTE] ================================================ @@ -825,7 +825,7 @@ checking it out and switching to it. If so, just use the command $ git branch [startingpoint] ------------ -which will simply _create_ the branch, but will not do anything further. +which will simply _create_ the branch, but will not do anything further. You can then later -- once you decide that you want to actually develop on that branch -- switch to that branch with a regular `git checkout` with the branchname as the argument. @@ -884,7 +884,7 @@ $ gitk --all will show you graphically both of your branches (that's what the `\--all` means: normally it will just show you your current `HEAD`) and their histories. You can also see exactly how they came to be from a common -source. +source. Anyway, let's exit `gitk` (`^Q` or the File menu), and decide that we want to merge the work we did on the `mybranch` branch into the `master` @@ -905,8 +905,8 @@ of it as it can automatically (which in this case is just merge the `example` file, which had no differences in the `mybranch` branch), and say: ---------------- - Auto-merging hello - CONFLICT (content): Merge conflict in hello + Auto-merging hello + CONFLICT (content): Merge conflict in hello Automatic merge failed; fix up by hand ---------------- @@ -1387,7 +1387,7 @@ repository. Kernel.org mirror network takes care of the propagation to other publicly visible machines: ------------ -$ git push master.kernel.org:/pub/scm/git/git.git/ +$ git push master.kernel.org:/pub/scm/git/git.git/ ------------ diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt index e38a1f1405..18d49d2c3b 100644 --- a/Documentation/diff-format.txt +++ b/Documentation/diff-format.txt @@ -1,7 +1,7 @@ The output format from "git-diff-index", "git-diff-tree" and "git-diff-files" are very similar. -These commands all compare two sets of things; what is +These commands all compare two sets of things; what is compared differs: git-diff-index :: @@ -139,28 +139,28 @@ index fabadb8,cc95eb0..4866510 --- a/describe.c +++ b/describe.c @@@ -98,20 -98,12 +98,20 @@@ - return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1; + return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1; } - + - static void describe(char *arg) -static void describe(struct commit *cmit, int last_one) ++static void describe(char *arg, int last_one) { + unsigned char sha1[20]; + struct commit *cmit; - struct commit_list *list; - static int initialized = 0; - struct commit_name *n; - + struct commit_list *list; + static int initialized = 0; + struct commit_name *n; + + if (get_sha1(arg, sha1) < 0) + usage(describe_usage); + cmit = lookup_commit_reference(sha1); + if (!cmit) + usage(describe_usage); + - if (!initialized) { - initialized = 1; - for_each_ref(get_name); + if (!initialized) { + initialized = 1; + for_each_ref(get_name); ------------ 1. It is preceded with a "git diff" header, that looks like @@ -233,4 +233,3 @@ parents). When shown by `git diff-files -c`, it compares the two unresolved merge parents with the working tree file (i.e. file1 is stage 2 aka "our version", file2 is stage 3 aka "their version"). - diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 1689c74817..b2a05937f9 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -100,8 +100,8 @@ that matches other criteria, nothing is selected. --find-copies-harder:: - For performance reasons, by default, -C option finds copies only - if the original file of the copy was modified in the same + For performance reasons, by default, -C option finds copies only + if the original file of the copy was modified in the same changeset. This flag makes the command inspect unmodified files as candidates for the source of copy. This is a very expensive operation for large diff --git a/Documentation/diffcore.txt b/Documentation/diffcore.txt index 34cd306bb1..c6a983a5d5 100644 --- a/Documentation/diffcore.txt +++ b/Documentation/diffcore.txt @@ -71,7 +71,7 @@ The first transformation in the chain is diffcore-pathspec, and is controlled by giving the pathname parameters to the git-diff-* commands on the command line. The pathspec is used to limit the world diff operates in. It removes the filepairs -outside the specified set of pathnames. E.g. If the input set +outside the specified set of pathnames. E.g. If the input set of filepairs included: ------------------------------------------------ @@ -269,4 +269,3 @@ Documentation *.c t ------------------------------------------------ - diff --git a/Documentation/docbook-xsl.css b/Documentation/docbook-xsl.css index 8821e305dd..b878b385c6 100644 --- a/Documentation/docbook-xsl.css +++ b/Documentation/docbook-xsl.css @@ -1,286 +1,286 @@ -/* - CSS stylesheet for XHTML produced by DocBook XSL stylesheets. - Tested with XSL stylesheets 1.61.2, 1.67.2 -*/ - -span.strong { - font-weight: bold; -} - -body blockquote { - margin-top: .75em; - line-height: 1.5; - margin-bottom: .75em; -} - -html body { - margin: 1em 5% 1em 5%; - line-height: 1.2; -} - -body div { - margin: 0; -} - -h1, h2, h3, h4, h5, h6, -div.toc p b, -div.list-of-figures p b, -div.list-of-tables p b, -div.abstract p.title -{ - color: #527bbd; - font-family: tahoma, verdana, sans-serif; -} - -div.toc p:first-child, -div.list-of-figures p:first-child, -div.list-of-tables p:first-child, -div.example p.title -{ - margin-bottom: 0.2em; -} - -body h1 { - margin: .0em 0 0 -4%; - line-height: 1.3; - border-bottom: 2px solid silver; -} - -body h2 { - margin: 0.5em 0 0 -4%; - line-height: 1.3; - border-bottom: 2px solid silver; -} - -body h3 { - margin: .8em 0 0 -3%; - line-height: 1.3; -} - -body h4 { - margin: .8em 0 0 -3%; - line-height: 1.3; -} - -body h5 { - margin: .8em 0 0 -2%; - line-height: 1.3; -} - -body h6 { - margin: .8em 0 0 -1%; - line-height: 1.3; -} - -body hr { - border: none; /* Broken on IE6 */ -} -div.footnotes hr { - border: 1px solid silver; -} - -div.navheader th, div.navheader td, div.navfooter td { - font-family: sans-serif; - font-size: 0.9em; - font-weight: bold; - color: #527bbd; -} -div.navheader img, div.navfooter img { - border-style: none; -} -div.navheader a, div.navfooter a { - font-weight: normal; -} -div.navfooter hr { - border: 1px solid silver; -} - -body td { - line-height: 1.2 -} - -body th { - line-height: 1.2; -} - -ol { - line-height: 1.2; -} - -ul, body dir, body menu { - line-height: 1.2; -} - -html { - margin: 0; - padding: 0; -} - -body h1, body h2, body h3, body h4, body h5, body h6 { - margin-left: 0 -} - -body pre { - margin: 0.5em 10% 0.5em 1em; - line-height: 1.0; - color: navy; -} - -tt.literal, code.literal { - color: navy; -} - -div.literallayout p { - padding: 0em; - margin: 0em; -} - -div.literallayout { - font-family: monospace; -# margin: 0.5em 10% 0.5em 1em; - margin: 0em; - color: navy; - border: 1px solid silver; - background: #f4f4f4; - padding: 0.5em; -} - -.programlisting, .screen { - border: 1px solid silver; - background: #f4f4f4; - margin: 0.5em 10% 0.5em 0; - padding: 0.5em 1em; -} - -div.sidebar { - background: #ffffee; - margin: 1.0em 10% 0.5em 0; - padding: 0.5em 1em; - border: 1px solid silver; -} -div.sidebar * { padding: 0; } -div.sidebar div { margin: 0; } -div.sidebar p.title { - font-family: sans-serif; - margin-top: 0.5em; - margin-bottom: 0.2em; -} - -div.bibliomixed { - margin: 0.5em 5% 0.5em 1em; -} - -div.glossary dt { - font-weight: bold; -} -div.glossary dd p { - margin-top: 0.2em; -} - -dl { - margin: .8em 0; - line-height: 1.2; -} - -dt { - margin-top: 0.5em; -} - -dt span.term { - font-style: italic; -} - -div.variablelist dd p { - margin-top: 0; -} - -div.itemizedlist li, div.orderedlist li { - margin-left: -0.8em; - margin-top: 0.5em; -} - -ul, ol { - list-style-position: outside; -} - -div.sidebar ul, div.sidebar ol { - margin-left: 2.8em; -} - -div.itemizedlist p.title, -div.orderedlist p.title, -div.variablelist p.title -{ - margin-bottom: -0.8em; -} - -div.revhistory table { - border-collapse: collapse; - border: none; -} -div.revhistory th { - border: none; - color: #527bbd; - font-family: tahoma, verdana, sans-serif; -} -div.revhistory td { - border: 1px solid silver; -} - -/* Keep TOC and index lines close together. */ -div.toc dl, div.toc dt, -div.list-of-figures dl, div.list-of-figures dt, -div.list-of-tables dl, div.list-of-tables dt, -div.indexdiv dl, div.indexdiv dt -{ - line-height: normal; - margin-top: 0; - margin-bottom: 0; -} - -/* - Table styling does not work because of overriding attributes in - generated HTML. -*/ -div.table table, -div.informaltable table -{ - margin-left: 0; - margin-right: 5%; - margin-bottom: 0.8em; -} -div.informaltable table -{ - margin-top: 0.4em -} -div.table thead, -div.table tfoot, -div.table tbody, -div.informaltable thead, -div.informaltable tfoot, -div.informaltable tbody -{ - /* No effect in IE6. */ - border-top: 2px solid #527bbd; - border-bottom: 2px solid #527bbd; -} -div.table thead, div.table tfoot, -div.informaltable thead, div.informaltable tfoot -{ - font-weight: bold; -} - -div.mediaobject img { - border: 1px solid silver; - margin-bottom: 0.8em; -} -div.figure p.title, -div.table p.title -{ - margin-top: 1em; - margin-bottom: 0.4em; -} - -@media print { - div.navheader, div.navfooter { display: none; } -} +/* + CSS stylesheet for XHTML produced by DocBook XSL stylesheets. + Tested with XSL stylesheets 1.61.2, 1.67.2 +*/ + +span.strong { + font-weight: bold; +} + +body blockquote { + margin-top: .75em; + line-height: 1.5; + margin-bottom: .75em; +} + +html body { + margin: 1em 5% 1em 5%; + line-height: 1.2; +} + +body div { + margin: 0; +} + +h1, h2, h3, h4, h5, h6, +div.toc p b, +div.list-of-figures p b, +div.list-of-tables p b, +div.abstract p.title +{ + color: #527bbd; + font-family: tahoma, verdana, sans-serif; +} + +div.toc p:first-child, +div.list-of-figures p:first-child, +div.list-of-tables p:first-child, +div.example p.title +{ + margin-bottom: 0.2em; +} + +body h1 { + margin: .0em 0 0 -4%; + line-height: 1.3; + border-bottom: 2px solid silver; +} + +body h2 { + margin: 0.5em 0 0 -4%; + line-height: 1.3; + border-bottom: 2px solid silver; +} + +body h3 { + margin: .8em 0 0 -3%; + line-height: 1.3; +} + +body h4 { + margin: .8em 0 0 -3%; + line-height: 1.3; +} + +body h5 { + margin: .8em 0 0 -2%; + line-height: 1.3; +} + +body h6 { + margin: .8em 0 0 -1%; + line-height: 1.3; +} + +body hr { + border: none; /* Broken on IE6 */ +} +div.footnotes hr { + border: 1px solid silver; +} + +div.navheader th, div.navheader td, div.navfooter td { + font-family: sans-serif; + font-size: 0.9em; + font-weight: bold; + color: #527bbd; +} +div.navheader img, div.navfooter img { + border-style: none; +} +div.navheader a, div.navfooter a { + font-weight: normal; +} +div.navfooter hr { + border: 1px solid silver; +} + +body td { + line-height: 1.2 +} + +body th { + line-height: 1.2; +} + +ol { + line-height: 1.2; +} + +ul, body dir, body menu { + line-height: 1.2; +} + +html { + margin: 0; + padding: 0; +} + +body h1, body h2, body h3, body h4, body h5, body h6 { + margin-left: 0 +} + +body pre { + margin: 0.5em 10% 0.5em 1em; + line-height: 1.0; + color: navy; +} + +tt.literal, code.literal { + color: navy; +} + +div.literallayout p { + padding: 0em; + margin: 0em; +} + +div.literallayout { + font-family: monospace; +# margin: 0.5em 10% 0.5em 1em; + margin: 0em; + color: navy; + border: 1px solid silver; + background: #f4f4f4; + padding: 0.5em; +} + +.programlisting, .screen { + border: 1px solid silver; + background: #f4f4f4; + margin: 0.5em 10% 0.5em 0; + padding: 0.5em 1em; +} + +div.sidebar { + background: #ffffee; + margin: 1.0em 10% 0.5em 0; + padding: 0.5em 1em; + border: 1px solid silver; +} +div.sidebar * { padding: 0; } +div.sidebar div { margin: 0; } +div.sidebar p.title { + font-family: sans-serif; + margin-top: 0.5em; + margin-bottom: 0.2em; +} + +div.bibliomixed { + margin: 0.5em 5% 0.5em 1em; +} + +div.glossary dt { + font-weight: bold; +} +div.glossary dd p { + margin-top: 0.2em; +} + +dl { + margin: .8em 0; + line-height: 1.2; +} + +dt { + margin-top: 0.5em; +} + +dt span.term { + font-style: italic; +} + +div.variablelist dd p { + margin-top: 0; +} + +div.itemizedlist li, div.orderedlist li { + margin-left: -0.8em; + margin-top: 0.5em; +} + +ul, ol { + list-style-position: outside; +} + +div.sidebar ul, div.sidebar ol { + margin-left: 2.8em; +} + +div.itemizedlist p.title, +div.orderedlist p.title, +div.variablelist p.title +{ + margin-bottom: -0.8em; +} + +div.revhistory table { + border-collapse: collapse; + border: none; +} +div.revhistory th { + border: none; + color: #527bbd; + font-family: tahoma, verdana, sans-serif; +} +div.revhistory td { + border: 1px solid silver; +} + +/* Keep TOC and index lines close together. */ +div.toc dl, div.toc dt, +div.list-of-figures dl, div.list-of-figures dt, +div.list-of-tables dl, div.list-of-tables dt, +div.indexdiv dl, div.indexdiv dt +{ + line-height: normal; + margin-top: 0; + margin-bottom: 0; +} + +/* + Table styling does not work because of overriding attributes in + generated HTML. +*/ +div.table table, +div.informaltable table +{ + margin-left: 0; + margin-right: 5%; + margin-bottom: 0.8em; +} +div.informaltable table +{ + margin-top: 0.4em +} +div.table thead, +div.table tfoot, +div.table tbody, +div.informaltable thead, +div.informaltable tfoot, +div.informaltable tbody +{ + /* No effect in IE6. */ + border-top: 2px solid #527bbd; + border-bottom: 2px solid #527bbd; +} +div.table thead, div.table tfoot, +div.informaltable thead, div.informaltable tfoot +{ + font-weight: bold; +} + +div.mediaobject img { + border: 1px solid silver; + margin-bottom: 0.8em; +} +div.figure p.title, +div.table p.title +{ + margin-top: 1em; + margin-bottom: 0.4em; +} + +@media print { + div.navheader, div.navfooter { display: none; } +} diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt index bdc7332c7b..da034223f3 100644 --- a/Documentation/fetch-options.txt +++ b/Documentation/fetch-options.txt @@ -52,4 +52,3 @@ Deepen the history of a 'shallow' repository created by `git clone` with `--depth=` option (see gitlink:git-clone[1]) by the specified number of commits. - diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt index a0c9f68580..76d2b05854 100644 --- a/Documentation/git-add.txt +++ b/Documentation/git-add.txt @@ -228,4 +228,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt index f3387f5d09..e4a6b3a6f0 100644 --- a/Documentation/git-am.txt +++ b/Documentation/git-am.txt @@ -158,4 +158,3 @@ Documentation by Petr Baudis, Junio C Hamano and the git-list parameters supplied. If it cannot find the remote branch a merge comes from -it will just import it as a regular commit. If it can find it, it will mark it -as a merge whenever possible (see discussion below). +it will just import it as a regular commit. If it can find it, it will mark it +as a merge whenever possible (see discussion below). -The script expects you to provide the key roots where it can start the import -from an 'initial import' or 'tag' type of Arch commit. It will follow and -import new branches within the provided roots. +The script expects you to provide the key roots where it can start the import +from an 'initial import' or 'tag' type of Arch commit. It will follow and +import new branches within the provided roots. -It expects to be dealing with one project only. If it sees -branches that have different roots, it will refuse to run. In that case, -edit your parameters to define clearly the scope of the -import. +It expects to be dealing with one project only. If it sees +branches that have different roots, it will refuse to run. In that case, +edit your parameters to define clearly the scope of the +import. -`git-archimport` uses `tla` extensively in the background to access the +`git-archimport` uses `tla` extensively in the background to access the Arch repository. Make sure you have a recent version of `tla` available in the path. `tla` must -know about the repositories you pass to `git-archimport`. +know about the repositories you pass to `git-archimport`. -For the initial import `git-archimport` expects to find itself in an empty -directory. To follow the development of a project that uses Arch, rerun -`git-archimport` with the same parameters as the initial import to perform +For the initial import `git-archimport` expects to find itself in an empty +directory. To follow the development of a project that uses Arch, rerun +`git-archimport` with the same parameters as the initial import to perform incremental imports. While git-archimport will try to create sensible branch names for the @@ -54,15 +54,15 @@ convert Arch repositories that had been rotated periodically. MERGES ------ -Patch merge data from Arch is used to mark merges in git as well. git +Patch merge data from Arch is used to mark merges in git as well. git does not care much about tracking patches, and only considers a merge when a branch incorporates all the commits since the point they forked. The end result -is that git will have a good idea of how far branches have diverged. So the +is that git will have a good idea of how far branches have diverged. So the import process does lose some patch-trading metadata. -Fortunately, when you try and merge branches imported from Arch, -git will find a good merge base, and it has a good chance of identifying -patches that have been traded out-of-sequence between the branches. +Fortunately, when you try and merge branches imported from Arch, +git will find a good merge base, and it has a good chance of identifying +patches that have been traded out-of-sequence between the branches. OPTIONS ------- @@ -71,10 +71,10 @@ OPTIONS Display usage. -v:: - Verbose output. + Verbose output. -T:: - Many tags. Will create a tag for every commit, reflecting the commit + Many tags. Will create a tag for every commit, reflecting the commit name in the Arch repository. -f:: @@ -104,7 +104,7 @@ OPTIONS :: - Archive/branch identifier in a format that `tla log` understands. + Archive/branch identifier in a format that `tla log` understands. Author @@ -118,4 +118,3 @@ Documentation by Junio C Hamano, Martin Langhoff and the git-list +'git bisect' DESCRIPTION ----------- @@ -200,4 +200,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt index 8dc5171f5e..8d72bb9368 100644 --- a/Documentation/git-branch.txt +++ b/Documentation/git-branch.txt @@ -158,4 +158,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt index 075c0d05ef..afa095c795 100644 --- a/Documentation/git-cat-file.txt +++ b/Documentation/git-cat-file.txt @@ -71,4 +71,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt index 918d8ee720..ea26da8e21 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -215,4 +215,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt index 68bba98260..47b1e8c2fc 100644 --- a/Documentation/git-cherry-pick.txt +++ b/Documentation/git-cherry-pick.txt @@ -68,4 +68,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-cherry.txt b/Documentation/git-cherry.txt index 27b67b81a5..b62c97097f 100644 --- a/Documentation/git-cherry.txt +++ b/Documentation/git-cherry.txt @@ -64,4 +64,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 644bf126fb..2461c0ec2d 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -175,4 +175,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt index 504a3aa1b4..9586b97291 100644 --- a/Documentation/git-commit-tree.txt +++ b/Documentation/git-commit-tree.txt @@ -40,7 +40,7 @@ OPTIONS -p :: Each '-p' indicates the id of a parent commit object. - + Commit Information ------------------ @@ -107,4 +107,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-cvsexportcommit.txt b/Documentation/git-cvsexportcommit.txt index da5c242241..827711c3c9 100644 --- a/Documentation/git-cvsexportcommit.txt +++ b/Documentation/git-cvsexportcommit.txt @@ -14,19 +14,19 @@ SYNOPSIS DESCRIPTION ----------- Exports a commit from GIT to a CVS checkout, making it easier -to merge patches from a git repository into a CVS repository. +to merge patches from a git repository into a CVS repository. -Execute it from the root of the CVS working copy. GIT_DIR must be defined. +Execute it from the root of the CVS working copy. GIT_DIR must be defined. See examples below. -It does its best to do the safe thing, it will check that the files are -unchanged and up to date in the CVS checkout, and it will not autocommit +It does its best to do the safe thing, it will check that the files are +unchanged and up to date in the CVS checkout, and it will not autocommit by default. Supports file additions, removals, and commits that affect binary files. If the commit is a merge commit, you must tell git-cvsexportcommit what parent -should the changeset be done against. +should the changeset be done against. OPTIONS ------- @@ -55,7 +55,7 @@ OPTIONS Force the parent commit, even if it is not a direct parent. -m:: - Prepend the commit message with the provided prefix. + Prepend the commit message with the provided prefix. Useful for patch series and the like. -u:: @@ -73,7 +73,7 @@ Merge one patch into CVS:: $ export GIT_DIR=~/project/.git $ cd ~/project_cvs_checkout $ git-cvsexportcommit -v -$ cvs commit -F .mgs +$ cvs commit -F .mgs ------------ Merge pending patches into CVS automatically -- only if you really know what you are doing :: @@ -95,4 +95,3 @@ Documentation by Martin Langhoff GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-cvsimport.txt b/Documentation/git-cvsimport.txt index e0be856546..3985e0164b 100644 --- a/Documentation/git-cvsimport.txt +++ b/Documentation/git-cvsimport.txt @@ -37,7 +37,7 @@ OPTIONS -d :: The root of the CVS archive. May be local (a simple path) or remote; - currently, only the :local:, :ext: and :pserver: access methods + currently, only the :local:, :ext: and :pserver: access methods are supported. If not given, git-cvsimport will try to read it from `CVS/Root`. If no such file exists, it checks for the `CVSROOT` environment variable. @@ -67,7 +67,7 @@ the old cvs2git tool. -k:: Kill keywords: will extract files with '-kk' from the CVS archive to avoid noisy changesets. Highly recommended, but off by default - to preserve compatibility with early imported trees. + to preserve compatibility with early imported trees. -u:: Convert underscores in tag and branch names to dots. @@ -89,15 +89,15 @@ If you need to pass multiple options, separate them with a comma. Instead of calling cvsps, read the provided cvsps output file. Useful for debugging or when cvsps is being handled outside cvsimport. --m:: +-m:: Attempt to detect merges based on the commit message. This option - will enable default regexes that try to capture the name source - branch name from the commit message. + will enable default regexes that try to capture the name source + branch name from the commit message. -M :: Attempt to detect merges based on the commit message with a custom regex. It can be used with '-m' to also see the default regexes. - You must escape forward slashes. + You must escape forward slashes. -S :: Skip paths matching the regex. @@ -156,4 +156,3 @@ Documentation by Matthias Urlichs . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt index 9ddab71203..4b30b18b42 100644 --- a/Documentation/git-daemon.txt +++ b/Documentation/git-daemon.txt @@ -235,4 +235,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt index dc47b65ced..ac23e28f27 100644 --- a/Documentation/git-describe.txt +++ b/Documentation/git-describe.txt @@ -124,4 +124,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt index 8d06775a6b..5eacab08dc 100644 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.txt @@ -908,4 +908,3 @@ Documentation by Shawn O. Pearce . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-fmt-merge-msg.txt b/Documentation/git-fmt-merge-msg.txt index 4913c2552f..6affc5bb4d 100644 --- a/Documentation/git-fmt-merge-msg.txt +++ b/Documentation/git-fmt-merge-msg.txt @@ -60,4 +60,3 @@ Documentation by Petr Baudis, Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-fsck.txt b/Documentation/git-fsck.txt index ed6413a3c7..234c22f57f 100644 --- a/Documentation/git-fsck.txt +++ b/Documentation/git-fsck.txt @@ -145,4 +145,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index c5a5dad1ce..97faaa1d3a 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@ -144,4 +144,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-hash-object.txt b/Documentation/git-hash-object.txt index 5edc36f060..616f196d81 100644 --- a/Documentation/git-hash-object.txt +++ b/Documentation/git-hash-object.txt @@ -18,7 +18,7 @@ work tree), and optionally writes the resulting object into the object database. Reports its object ID to its standard output. This is used by "git-cvsimport" to update the index without modifying files in the work tree. When is not -specified, it defaults to "blob". +specified, it defaults to "blob". OPTIONS ------- @@ -43,4 +43,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list ' specification can be either a single pattern, or a pair of such patterns separated by a colon ":" (this means that a ref name -cannot have a colon in it). A single pattern '' is just a +cannot have a colon in it). A single pattern '' is just a shorthand for ':'. Each pattern pair consists of the source side (before the colon) diff --git a/Documentation/git-index-pack.txt b/Documentation/git-index-pack.txt index 226926964e..a8a7f6f04b 100644 --- a/Documentation/git-index-pack.txt +++ b/Documentation/git-index-pack.txt @@ -98,4 +98,3 @@ Documentation by Sergey Vlasov GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-init-db.txt b/Documentation/git-init-db.txt index 5412135d76..ab0201aec2 100644 --- a/Documentation/git-init-db.txt +++ b/Documentation/git-init-db.txt @@ -16,4 +16,3 @@ DESCRIPTION This is a synonym for gitlink:git-init[1]. Please refer to the documentation of that command. - diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt index 1b64d3ab03..413ed65143 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.txt @@ -108,4 +108,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-local-fetch.txt b/Documentation/git-local-fetch.txt index 51389ef37d..19b5f8895c 100644 --- a/Documentation/git-local-fetch.txt +++ b/Documentation/git-local-fetch.txt @@ -62,4 +62,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.txt index ad7f1b9202..7b78599673 100644 --- a/Documentation/git-ls-tree.txt +++ b/Documentation/git-ls-tree.txt @@ -92,4 +92,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-mailinfo.txt b/Documentation/git-mailinfo.txt index 16956951dd..64aa6a1ea6 100644 --- a/Documentation/git-mailinfo.txt +++ b/Documentation/git-mailinfo.txt @@ -67,4 +67,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-mailsplit.txt b/Documentation/git-mailsplit.txt index abb0903696..c4f4cabbdc 100644 --- a/Documentation/git-mailsplit.txt +++ b/Documentation/git-mailsplit.txt @@ -56,4 +56,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt index 3190aed108..6b71880ec4 100644 --- a/Documentation/git-merge-base.txt +++ b/Documentation/git-merge-base.txt @@ -40,4 +40,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list git-merge-index cat AA MM cat: : No such file or directory @@ -85,4 +85,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt index 912ef29efc..d285cba033 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@ -95,7 +95,7 @@ When things cleanly merge, these things happen: 1. the results are updated both in the index file and in your working tree, 2. index file is written out as a tree, -3. the tree gets committed, and +3. the tree gets committed, and 4. the `HEAD` pointer gets advanced. Because of 2., we require that the original state of the index diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt index add01e855a..b89c51c65b 100644 --- a/Documentation/git-mergetool.txt +++ b/Documentation/git-mergetool.txt @@ -43,4 +43,3 @@ Documentation by Theodore Y Ts'o. GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt index 2860a3d1ba..0ac3be10c7 100644 --- a/Documentation/git-mktag.txt +++ b/Documentation/git-mktag.txt @@ -44,4 +44,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-mv.txt b/Documentation/git-mv.txt index 6756b76bb1..2c9cf743c7 100644 --- a/Documentation/git-mv.txt +++ b/Documentation/git-mv.txt @@ -51,4 +51,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt index cfe127ad9e..e3549b5044 100644 --- a/Documentation/git-pack-objects.txt +++ b/Documentation/git-pack-objects.txt @@ -185,4 +185,3 @@ gitlink:git-prune-packed[1] GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-pack-redundant.txt b/Documentation/git-pack-redundant.txt index 94bbea0db2..f2ceebac4b 100644 --- a/Documentation/git-pack-redundant.txt +++ b/Documentation/git-pack-redundant.txt @@ -17,7 +17,7 @@ are redundant. The output is suitable for piping to 'xargs rm' if you are in the root of the repository. git-pack-redundant accepts a list of objects on standard input. Any objects -given will be ignored when checking which packs are required. This makes the +given will be ignored when checking which packs are required. This makes the following command useful when wanting to remove packs which contain unreachable objects. @@ -55,4 +55,3 @@ gitlink:git-prune-packed[1] GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-patch-id.txt b/Documentation/git-patch-id.txt index a7e9fd021a..ad528a9224 100644 --- a/Documentation/git-patch-id.txt +++ b/Documentation/git-patch-id.txt @@ -40,4 +40,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-peek-remote.txt b/Documentation/git-peek-remote.txt index 74f37bd904..abc171266a 100644 --- a/Documentation/git-peek-remote.txt +++ b/Documentation/git-peek-remote.txt @@ -52,4 +52,3 @@ Documentation by Junio C Hamano. GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-prune-packed.txt b/Documentation/git-prune-packed.txt index 310033e460..3800edb7bb 100644 --- a/Documentation/git-prune-packed.txt +++ b/Documentation/git-prune-packed.txt @@ -50,4 +50,3 @@ gitlink:git-repack[1] GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-prune.txt b/Documentation/git-prune.txt index 0b44f3015d..50ee5bddd0 100644 --- a/Documentation/git-prune.txt +++ b/Documentation/git-prune.txt @@ -58,4 +58,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index e9ad10672a..366c5dbdce 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -110,4 +110,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-quiltimport.txt b/Documentation/git-quiltimport.txt index 296937a416..1c3ef4c593 100644 --- a/Documentation/git-quiltimport.txt +++ b/Documentation/git-quiltimport.txt @@ -58,4 +58,3 @@ Documentation by Eric Biederman GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt index acb57447a8..84184d6294 100644 --- a/Documentation/git-read-tree.txt +++ b/Documentation/git-read-tree.txt @@ -356,4 +356,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt index 1e343bcdcd..f717e1e30c 100644 --- a/Documentation/git-reflog.txt +++ b/Documentation/git-reflog.txt @@ -65,4 +65,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-relink.txt b/Documentation/git-relink.txt index aca60120c8..fe631bb3dd 100644 --- a/Documentation/git-relink.txt +++ b/Documentation/git-relink.txt @@ -34,4 +34,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt index 3dde7134a5..ab232c2f68 100644 --- a/Documentation/git-remote.txt +++ b/Documentation/git-remote.txt @@ -128,4 +128,3 @@ Documentation by J. Bruce Fields and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt index 2847c9b8d7..c33a512ffb 100644 --- a/Documentation/git-repack.txt +++ b/Documentation/git-repack.txt @@ -101,4 +101,3 @@ gitlink:git-prune-packed[1] GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-request-pull.txt b/Documentation/git-request-pull.txt index 478a5fd6b7..087eeb7cc2 100644 --- a/Documentation/git-request-pull.txt +++ b/Documentation/git-request-pull.txt @@ -37,4 +37,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt index 7757abe621..e1cb4ef856 100644 --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.txt @@ -286,4 +286,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt index 8081bbaffa..69db498447 100644 --- a/Documentation/git-revert.txt +++ b/Documentation/git-revert.txt @@ -56,4 +56,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt index a65f24a0f6..78f45dca2e 100644 --- a/Documentation/git-rm.txt +++ b/Documentation/git-rm.txt @@ -95,4 +95,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-runstatus.txt b/Documentation/git-runstatus.txt index 8bb52f4687..dee5d0da9d 100644 --- a/Documentation/git-runstatus.txt +++ b/Documentation/git-runstatus.txt @@ -66,4 +66,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-shell.txt b/Documentation/git-shell.txt index 228b9f14f3..48f2d57b7b 100644 --- a/Documentation/git-shell.txt +++ b/Documentation/git-shell.txt @@ -32,4 +32,3 @@ Documentation by Petr Baudis and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt index 15cc6f77c1..2220ef6ea8 100644 --- a/Documentation/git-shortlog.txt +++ b/Documentation/git-shortlog.txt @@ -56,4 +56,3 @@ Documentation by Junio C Hamano. GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-show-index.txt b/Documentation/git-show-index.txt index be09b62beb..764d99356b 100644 --- a/Documentation/git-show-index.txt +++ b/Documentation/git-show-index.txt @@ -32,4 +32,3 @@ Documentation by Junio C Hamano GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-show.txt b/Documentation/git-show.txt index 34c5caf2d0..a42e121150 100644 --- a/Documentation/git-show.txt +++ b/Documentation/git-show.txt @@ -84,4 +84,3 @@ This manual page is a stub. You can help the git documentation by expanding it. GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-ssh-fetch.txt b/Documentation/git-ssh-fetch.txt index 192b1f15a9..aaf3db06da 100644 --- a/Documentation/git-ssh-fetch.txt +++ b/Documentation/git-ssh-fetch.txt @@ -48,4 +48,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt index bdae7d87dc..e97d15e8f2 100644 --- a/Documentation/git-svnimport.txt +++ b/Documentation/git-svnimport.txt @@ -174,4 +174,3 @@ Documentation by Matthias Urlichs . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-tar-tree.txt b/Documentation/git-tar-tree.txt index 7bde73b1b8..2d01d9666f 100644 --- a/Documentation/git-tar-tree.txt +++ b/Documentation/git-tar-tree.txt @@ -90,4 +90,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list :: Directly insert the specified info into the index. - + --index-info:: Read index information from stdin. --chmod=(+|-)x:: - Set the execute permissions on the updated files. + Set the execute permissions on the updated files. --assume-unchanged, --no-assume-unchanged:: When these flags are specified, the object name recorded @@ -126,7 +126,7 @@ OPTIONS :: Files to act on. Note that files beginning with '.' are discarded. This includes - `./file` and `dir/./file`. If you don't want this, then use + `./file` and `dir/./file`. If you don't want this, then use cleaner names. The same applies to directories ending '/' and paths with '//' @@ -324,4 +324,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-verify-pack.txt b/Documentation/git-verify-pack.txt index 7a6132b016..f4c540f39b 100644 --- a/Documentation/git-verify-pack.txt +++ b/Documentation/git-verify-pack.txt @@ -51,4 +51,3 @@ Documentation by Junio C Hamano GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-verify-tag.txt b/Documentation/git-verify-tag.txt index 0f9bdb58dc..48d17fd9c4 100644 --- a/Documentation/git-verify-tag.txt +++ b/Documentation/git-verify-tag.txt @@ -29,4 +29,3 @@ Documentation by Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/git-whatchanged.txt b/Documentation/git-whatchanged.txt index 399bff3bbc..607df48f09 100644 --- a/Documentation/git-whatchanged.txt +++ b/Documentation/git-whatchanged.txt @@ -78,4 +78,3 @@ Documentation by David Greaves, Junio C Hamano and the git-list . GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt index 48c5894736..e9f82b97b9 100644 --- a/Documentation/gitk.txt +++ b/Documentation/gitk.txt @@ -99,4 +99,3 @@ Documentation by Junio C Hamano, Jonas Fonseca, and the git-list GIT --- Part of the gitlink:git[7] suite - diff --git a/Documentation/howto/rebase-and-edit.txt b/Documentation/howto/rebase-and-edit.txt index 646c55cc69..554909fe08 100644 --- a/Documentation/howto/rebase-and-edit.txt +++ b/Documentation/howto/rebase-and-edit.txt @@ -9,16 +9,16 @@ Abstract: In this article, Linus demonstrates how a broken commit On Sat, 13 Aug 2005, Linus Torvalds wrote: -> That's correct. Same things apply: you can move a patch over, and create a -> new one with a modified comment, but basically the _old_ commit will be +> That's correct. Same things apply: you can move a patch over, and create a +> new one with a modified comment, but basically the _old_ commit will be > immutable. Let me clarify. You can entirely _drop_ old branches, so commits may be immutable, but -nothing forces you to keep them. Of course, when you drop a commit, you'll -always end up dropping all the commits that depended on it, and if you -actually got somebody else to pull that commit you can't drop it from +nothing forces you to keep them. Of course, when you drop a commit, you'll +always end up dropping all the commits that depended on it, and if you +actually got somebody else to pull that commit you can't drop it from _their_ repository, but undoing things is not impossible. For example, let's say that you've made a mess of things: you've committed @@ -29,7 +29,7 @@ want to save "b" and "c". What you can do is # for reference git branch broken - # Reset the main branch to three parents back: this + # Reset the main branch to three parents back: this # effectively undoes the three top commits git reset HEAD^^^ git checkout -f @@ -59,7 +59,7 @@ Finally, check out the end result again: to see that everything looks sensible. -And then, you can just remove the broken branch if you decide you really +And then, you can just remove the broken branch if you decide you really don't want it: # remove 'broken' branch @@ -68,8 +68,8 @@ don't want it: # Prune old objects if you're really really sure git prune -And yeah, I'm sure there are other ways of doing this. And as usual, the -above is totally untested, and I just wrote it down in this email, so if +And yeah, I'm sure there are other ways of doing this. And as usual, the +above is totally untested, and I just wrote it down in this email, so if I've done something wrong, you'll have to figure it out on your own ;) Linus @@ -77,5 +77,3 @@ I've done something wrong, you'll have to figure it out on your own ;) To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html - - diff --git a/Documentation/howto/rebase-from-internal-branch.txt b/Documentation/howto/rebase-from-internal-branch.txt index 3b3a5c2e69..7a76045eb7 100644 --- a/Documentation/howto/rebase-from-internal-branch.txt +++ b/Documentation/howto/rebase-from-internal-branch.txt @@ -14,10 +14,10 @@ Petr Baudis writes: > Dear diary, on Sun, Aug 14, 2005 at 09:57:13AM CEST, I got a letter > where Junio C Hamano told me that... >> Linus Torvalds writes: ->> ->> > Junio, maybe you want to talk about how you move patches from your "pu" +>> +>> > Junio, maybe you want to talk about how you move patches from your "pu" >> > branch to the real branches. ->> +>> > Actually, wouldn't this be also precisely for what StGIT is intended to? Exactly my feeling. I was sort of waiting for Catalin to speak @@ -118,7 +118,7 @@ up your changes, along with other changes. where *your "master" head upstream --> #1 --> #2 --> #3 - used \ + used \ to be \--> #A --> #2' --> #3' --> #B --> #C *upstream head @@ -133,7 +133,7 @@ You fetch from upstream, but not merge. $ git fetch upstream This leaves the updated upstream head in .git/FETCH_HEAD but -does not touch your .git/HEAD nor .git/refs/heads/master. +does not touch your .git/HEAD nor .git/refs/heads/master. You run "git rebase" now. $ git rebase FETCH_HEAD master @@ -161,5 +161,3 @@ the #1' commit. To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html - - diff --git a/Documentation/howto/rebuild-from-update-hook.txt b/Documentation/howto/rebuild-from-update-hook.txt index 02621b54a0..8d55dfbfae 100644 --- a/Documentation/howto/rebuild-from-update-hook.txt +++ b/Documentation/howto/rebuild-from-update-hook.txt @@ -84,4 +84,3 @@ There are four things worth mentioning: - This is still crude and does not protect against simultaneous make invocations stomping on each other. I would need to add some locking mechanism for this. - diff --git a/Documentation/howto/revert-branch-rebase.txt b/Documentation/howto/revert-branch-rebase.txt index d88ec23a97..865a666324 100644 --- a/Documentation/howto/revert-branch-rebase.txt +++ b/Documentation/howto/revert-branch-rebase.txt @@ -146,7 +146,7 @@ Everything is in the good order. I do not need the temporary branch nor tag anymore, so remove them: ------------------------------------------------ -$ rm -f .git/refs/tags/pu-anchor +$ rm -f .git/refs/tags/pu-anchor $ git branch -d revert-c99 ------------------------------------------------ diff --git a/Documentation/howto/separating-topic-branches.txt b/Documentation/howto/separating-topic-branches.txt index 090e2c9b01..0d73b31224 100644 --- a/Documentation/howto/separating-topic-branches.txt +++ b/Documentation/howto/separating-topic-branches.txt @@ -12,7 +12,7 @@ up with a history like this: "master" o---o - \ "topic" + \ "topic" o---o---o---o---o---o At this point, "topic" contains something I know I want, but it @@ -29,11 +29,11 @@ start building on top of "master": $ git checkout -b topicA master ... pick and apply pieces from P.diff to build ... commits on topicA branch. - + o---o---o / "topicA" o---o"master" - \ "topic" + \ "topic" o---o---o---o---o---o Before doing each commit on "topicA" HEAD, I run "diff HEAD" @@ -59,7 +59,7 @@ other topic: /o---o---o |/ "topicA" o---o"master" - \ "topic" + \ "topic" o---o---o---o---o---o After I am done, I'd try a pretend-merge between "topicA" and @@ -73,7 +73,7 @@ After I am done, I'd try a pretend-merge between "topicA" and /o---o---o----------' |/ "topicA" o---o"master" - \ "topic" + \ "topic" o---o---o---o---o---o The last diff better not to show anything other than cleanups @@ -84,8 +84,7 @@ for crufts. Then I can finally clean things up: "topicB" o---o---o---o---o - / + / /o---o---o |/ "topicA" o---o"master" - diff --git a/Documentation/howto/use-git-daemon.txt b/Documentation/howto/use-git-daemon.txt index 1a1eb246bf..4e2f75cb61 100644 --- a/Documentation/howto/use-git-daemon.txt +++ b/Documentation/howto/use-git-daemon.txt @@ -49,4 +49,3 @@ Now, test your daemon with $ git ls-remote git://127.0.0.1/rule-the-world.git If this does not work, find out why, and submit a patch to this document. - diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index 56f1d8d69d..d64c259bb3 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -25,4 +25,3 @@ If there is no `-s` option, a built-in list of strategies is used instead (`git-merge-recursive` when merging a single head, `git-merge-octopus` otherwise). - diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt index d922e8e86c..c551ea61d2 100644 --- a/Documentation/pretty-formats.txt +++ b/Documentation/pretty-formats.txt @@ -121,4 +121,3 @@ The placeholders are: - '%Creset': reset color - '%m': left, right or boundary mark - '%n': newline - diff --git a/Documentation/pretty-options.txt b/Documentation/pretty-options.txt index 7d515be0fd..6338def5a7 100644 --- a/Documentation/pretty-options.txt +++ b/Documentation/pretty-options.txt @@ -11,4 +11,3 @@ command to re-code the commit log message in the encoding preferred by the user. For non plumbing commands this defaults to UTF-8. - diff --git a/Documentation/pull-fetch-param.txt b/Documentation/pull-fetch-param.txt index 8d4e950abc..b6eb7fc618 100644 --- a/Documentation/pull-fetch-param.txt +++ b/Documentation/pull-fetch-param.txt @@ -58,7 +58,7 @@ is often useful. + Some short-cut notations are also supported. + -* `tag ` means the same as `refs/tags/:refs/tags/`; +* `tag ` means the same as `refs/tags/:refs/tags/`; it requests fetching everything up to the given tag. * A parameter without a colon is equivalent to : when pulling/fetching, so it merges into the current diff --git a/Documentation/repository-layout.txt b/Documentation/repository-layout.txt index 15221b5320..4c92e375fe 100644 --- a/Documentation/repository-layout.txt +++ b/Documentation/repository-layout.txt @@ -177,4 +177,3 @@ shallow:: This is similar to `info/grafts` but is internally used and maintained by shallow clone mechanism. See `--depth` option to gitlink:git-clone[1] and gitlink:git-fetch[1]. - diff --git a/Documentation/technical/pack-format.txt b/Documentation/technical/pack-format.txt index 9ce3c473ae..e5b31c81fa 100644 --- a/Documentation/technical/pack-format.txt +++ b/Documentation/technical/pack-format.txt @@ -80,7 +80,7 @@ Pack Idx file: +--------------------------------+ | main | offset | | index | object name 00XXXXXXXXXXXXXXXX | | -table +--------------------------------+ | +table +--------------------------------+ | | offset | | | object name 00XXXXXXXXXXXXXXXX | | +--------------------------------+ | @@ -97,14 +97,14 @@ trailer | | packfile checksum | | +--------------------------------+ | | idxfile checksum | | +--------------------------------+ - .-------. + .-------. | Pack file entry: <+ packed object header: 1-byte size extension bit (MSB) type (next 3 bit) - size0 (lower 4-bit) + size0 (lower 4-bit) n-byte sizeN (as long as MSB is set, each 7-bit) size0..sizeN form 4+7+7+..+7 bit integer, size0 is the least significant part, and sizeN is the @@ -114,5 +114,5 @@ Pack file entry: <+ is the size before compression). If it is DELTA, then 20-byte base object name SHA1 (the size above is the - size of the delta data that follows). + size of the delta data that follows). delta data, deflated. diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index 7eaafa80e9..957cd00761 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -154,11 +154,11 @@ Author: Jamal Hadi Salim Date: Sat Dec 2 22:22:25 2006 -0800 [XFRM]: Fix aevent structuring to be more complete. - + aevents can not uniquely identify an SA. We break the ABI with this patch, but consensus is that since it is not yet utilized by any (known) application then it is fine (better do it now than later). - + Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller @@ -167,7 +167,7 @@ index 8be626f..d7aac9d 100644 --- a/Documentation/networking/xfrm_sync.txt +++ b/Documentation/networking/xfrm_sync.txt @@ -47,10 +47,13 @@ aevent_id structure looks like: - + struct xfrm_aevent_id { struct xfrm_usersa_id sa_id; + xfrm_address_t saddr; @@ -1056,7 +1056,7 @@ $ git show ------------------------------------------------- As a special shortcut, - + ------------------------------------------------- $ git commit -a ------------------------------------------------- @@ -1554,7 +1554,7 @@ history. Fortunately, git also keeps a log, called a "reflog", of all the previous values of each branch. So in this case you can still find the -old history using, for example, +old history using, for example, ------------------------------------------------- $ git log master@{1} @@ -1630,7 +1630,7 @@ If you decide you want the history back, you can always create a new reference pointing to it, for example, a new branch: ------------------------------------------------ -$ git branch recovered-branch 7281251ddd +$ git branch recovered-branch 7281251ddd ------------------------------------------------ Other types of dangling objects (blobs and trees) are also possible, and @@ -1793,7 +1793,7 @@ like this: you push your personal repo ------------------> your public repo - ^ | + ^ | | | | you pull | they pull | | @@ -2359,7 +2359,7 @@ the result would create a new merge commit, like this: \ \ a--b--c--m <-- mywork ................................................ - + However, if you prefer to keep the history in mywork a simple series of commits without any merges, you may instead choose to use gitlink:git-rebase[1]: @@ -2735,7 +2735,7 @@ must have at least one root, and while you can tie several different root objects together into one project by creating a commit object which has two or more separate roots as its ultimate parents, that's probably just going to confuse people. So aim for the notion of "one root object -per project", even if git itself does not enforce that. +per project", even if git itself does not enforce that. A <> symbolically identifies and can be used to sign other objects. It contains the identifier and type of @@ -2757,7 +2757,7 @@ independently of the contents or the type of the object: all objects can be validated by verifying that (a) their hashes match the content of the file and (b) the object successfully inflates to a stream of bytes that forms a sequence of + + + + . +size> + + . The structured objects can further have their structure and connectivity to other objects verified. This is generally done with @@ -2954,7 +2954,7 @@ cache, and the normal operation is to re-generate it completely from a known tree object, or update/compare it with a live tree that is being developed. If you blow the directory cache away entirely, you generally haven't lost any information as long as you have the name of the tree -that it described. +that it described. At the same time, the index is at the same time also the staging area for creating new trees, and creating a new tree always @@ -2974,7 +2974,7 @@ Generally, all "git" operations work on the index file. Some operations work *purely* on the index file (showing the current state of the index), but most operations move data to and from the index file. Either from the database or from the working directory. Thus there are four -main combinations: +main combinations: [[working-directory-to-index]] working directory -> index @@ -3437,7 +3437,7 @@ because you interrupted a "git fetch" with ^C or something like that, leaving _some_ of the new objects in the object database, but just dangling and useless. -Anyway, once you are sure that you're not interested in any dangling +Anyway, once you are sure that you're not interested in any dangling state, you can just prune all unreachable objects: ------------------------------------------------ @@ -3448,12 +3448,12 @@ and they'll be gone. But you should only run "git prune" on a quiescent repository - it's kind of like doing a filesystem fsck recovery: you don't want to do that while the filesystem is mounted. -(The same is true of "git-fsck" itself, btw - but since -git-fsck never actually *changes* the repository, it just reports -on what it found, git-fsck itself is never "dangerous" to run. -Running it while somebody is actually changing the repository can cause -confusing and scary messages, but it won't actually do anything bad. In -contrast, running "git prune" while somebody is actively changing the +(The same is true of "git-fsck" itself, btw - but since +git-fsck never actually *changes* the repository, it just reports +on what it found, git-fsck itself is never "dangerous" to run. +Running it while somebody is actually changing the repository can cause +confusing and scary messages, but it won't actually do anything bad. In +contrast, running "git prune" while somebody is actively changing the repository is a *BAD* idea). [[birdview-on-the-source-code]] diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 06c360b267..289c8067b5 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -43,5 +43,3 @@ test "$VN" = "$VC" || { echo >&2 "GIT_VERSION = $VN" echo "GIT_VERSION = $VN" >$GVF } - - diff --git a/INSTALL b/INSTALL index 361c65bacc..95269cc513 100644 --- a/INSTALL +++ b/INSTALL @@ -31,7 +31,7 @@ Issues of note: interactive tools. None of the core git stuff needs the wrapper, it's just a convenient shorthand and while it is documented in some places, you can always replace "git commit" with "git-commit" - instead. + instead. But let's face it, most of us don't have GNU interactive tools, and even if we had it, we wouldn't know what it does. I don't think it @@ -111,4 +111,3 @@ Issues of note: would instead give you a copy of what you see at: http://www.kernel.org/pub/software/scm/git/docs/ - diff --git a/arm/sha1.c b/arm/sha1.c index 11b1a048b4..9e3ae038e8 100644 --- a/arm/sha1.c +++ b/arm/sha1.c @@ -49,7 +49,7 @@ void SHA1_Update(SHA_CTX *c, const void *p, unsigned long n) void SHA1_Final(unsigned char *hash, SHA_CTX *c) { uint64_t bitlen; - uint32_t bitlen_hi, bitlen_lo; + uint32_t bitlen_hi, bitlen_lo; unsigned int i, offset, padlen; unsigned char bits[8]; static const unsigned char padding[64] = { 0x80, }; @@ -69,7 +69,7 @@ void SHA1_Final(unsigned char *hash, SHA_CTX *c) bits[5] = bitlen_lo >> 16; bits[6] = bitlen_lo >> 8; bits[7] = bitlen_lo; - SHA1_Update(c, bits, 8); + SHA1_Update(c, bits, 8); for (i = 0; i < 5; i++) { uint32_t v = c->hash[i]; diff --git a/arm/sha1_arm.S b/arm/sha1_arm.S index a328b73375..8c1cb99fb4 100644 --- a/arm/sha1_arm.S +++ b/arm/sha1_arm.S @@ -181,4 +181,3 @@ sha_transform: .L_sha_K: .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 - diff --git a/builtin-annotate.c b/builtin-annotate.c index 9db7cfe74c..fc43eed36b 100644 --- a/builtin-annotate.c +++ b/builtin-annotate.c @@ -22,4 +22,3 @@ int cmd_annotate(int argc, const char **argv, const char *prefix) return cmd_blame(argc + 1, nargv, prefix); } - diff --git a/builtin-diff-index.c b/builtin-diff-index.c index d90eba95a6..81e7167438 100644 --- a/builtin-diff-index.c +++ b/builtin-diff-index.c @@ -23,7 +23,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix) argc = setup_revisions(argc, argv, &rev, NULL); for (i = 1; i < argc; i++) { const char *arg = argv[i]; - + if (!strcmp(arg, "--cached")) cached = 1; else diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c index 5c145d2165..ae60fccea7 100644 --- a/builtin-fmt-merge-msg.c +++ b/builtin-fmt-merge-msg.c @@ -357,4 +357,3 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) return 0; } - diff --git a/builtin-fsck.c b/builtin-fsck.c index bacae5dfa6..944a496650 100644 --- a/builtin-fsck.c +++ b/builtin-fsck.c @@ -351,7 +351,7 @@ static int fsck_commit(struct commit *commit) if (!commit->parents && show_root) printf("root %s\n", sha1_to_hex(commit->object.sha1)); if (!commit->date) - printf("bad commit date in %s\n", + printf("bad commit date in %s\n", sha1_to_hex(commit->object.sha1)); return 0; } @@ -719,7 +719,7 @@ int cmd_fsck(int argc, char **argv, const char *prefix) heads = 0; for (i = 1; i < argc; i++) { - const char *arg = argv[i]; + const char *arg = argv[i]; if (*arg == '-') continue; diff --git a/builtin-ls-files.c b/builtin-ls-files.c index f7c066b24b..5398a41415 100644 --- a/builtin-ls-files.c +++ b/builtin-ls-files.c @@ -117,7 +117,7 @@ static void show_other_files(struct dir_struct *dir) if (0 <= pos) continue; /* exact match */ pos = -pos - 1; - if (pos < active_nr) { + if (pos < active_nr) { ce = active_cache[pos]; if (ce_namelen(ce) == len && !memcmp(ce->name, ent->name, len)) diff --git a/builtin-name-rev.c b/builtin-name-rev.c index d3c42ed67e..61eba343ab 100644 --- a/builtin-name-rev.c +++ b/builtin-name-rev.c @@ -290,4 +290,3 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix) return 0; } - diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 8b9740c277..3d396ca37a 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -252,7 +252,7 @@ static void *delta_against(void *buf, unsigned long size, struct object_entry *e delta_buf = diff_delta(otherbuf, othersize, buf, size, &delta_size, 0); if (!delta_buf || delta_size != entry->delta_size) - die("delta size changed"); + die("delta size changed"); free(buf); free(otherbuf); return delta_buf; diff --git a/builtin-rerere.c b/builtin-rerere.c index 8c2c8bdc18..f6409b93c1 100644 --- a/builtin-rerere.c +++ b/builtin-rerere.c @@ -434,4 +434,3 @@ int cmd_rerere(int argc, const char **argv, const char *prefix) path_list_clear(&merge_rr, 1); return 0; } - diff --git a/builtin-shortlog.c b/builtin-shortlog.c index 8d3f742d43..16af6199ab 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -331,4 +331,3 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) return 0; } - diff --git a/cache.h b/cache.h index 8a9d1f3883..5e7381eb1e 100644 --- a/cache.h +++ b/cache.h @@ -479,7 +479,7 @@ extern void prepare_packed_git(void); extern void reprepare_packed_git(void); extern void install_packed_git(struct packed_git *pack); -extern struct packed_git *find_sha1_pack(const unsigned char *sha1, +extern struct packed_git *find_sha1_pack(const unsigned char *sha1, struct packed_git *packs); extern void pack_report(void); diff --git a/commit.c b/commit.c index 5632e32685..57b69ca7fa 100644 --- a/commit.c +++ b/commit.c @@ -148,7 +148,7 @@ static int commit_graft_pos(const unsigned char *sha1) int register_commit_graft(struct commit_graft *graft, int ignore_dups) { int pos = commit_graft_pos(graft->sha1); - + if (0 <= pos) { if (ignore_dups) free(graft); @@ -406,7 +406,7 @@ struct commit_list * insert_by_date(struct commit *item, struct commit_list **li return commit_list_insert(item, pp); } - + void sort_by_date(struct commit_list **list) { struct commit_list *ret = NULL; @@ -1160,7 +1160,7 @@ void sort_in_topological_order_fn(struct commit_list ** list, int lifo, next = next->next; count++; } - + if (!count) return; /* allocate an array to help sort the list */ @@ -1188,11 +1188,11 @@ void sort_in_topological_order_fn(struct commit_list ** list, int lifo, } next=next->next; } - /* + /* * find the tips * - * tips are nodes not reachable from any other node in the list - * + * tips are nodes not reachable from any other node in the list + * * the tips serve as a starting set for the work queue. */ next=*list; @@ -1220,7 +1220,7 @@ void sort_in_topological_order_fn(struct commit_list ** list, int lifo, if (pn) { /* - * parents are only enqueued for emission + * parents are only enqueued for emission * when all their children have been emitted thereby * guaranteeing topological order. */ diff --git a/commit.h b/commit.h index 86e8dca0c9..75b43a53ed 100644 --- a/commit.h +++ b/commit.h @@ -66,7 +66,7 @@ extern unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit /** Removes the first commit from a list sorted by date, and adds all * of its parents. **/ -struct commit *pop_most_recent_commit(struct commit_list **list, +struct commit *pop_most_recent_commit(struct commit_list **list, unsigned int mark); struct commit *pop_commit(struct commit_list **stack); diff --git a/compat/mmap.c b/compat/mmap.c index 4cfaee3136..c9d46d1742 100644 --- a/compat/mmap.c +++ b/compat/mmap.c @@ -40,4 +40,3 @@ int git_munmap(void *start, size_t length) free(start); return 0; } - diff --git a/config.c b/config.c index 0614c2b29f..58d3ed5d37 100644 --- a/config.c +++ b/config.c @@ -621,7 +621,7 @@ static ssize_t find_beginning_of_line(const char* contents, size_t size, size_t equal_offset = size, bracket_offset = size; ssize_t offset; - for (offset = offset_-2; offset > 0 + for (offset = offset_-2; offset > 0 && contents[offset] != '\n'; offset--) switch (contents[offset]) { case '=': equal_offset = offset; break; @@ -989,4 +989,3 @@ int git_config_rename_section(const char *old_name, const char *new_name) free(config_filename); return ret; } - diff --git a/config.mak.in b/config.mak.in index eb9d7a5549..a3032e389f 100644 --- a/config.mak.in +++ b/config.mak.in @@ -38,4 +38,3 @@ NO_STRCASESTR=@NO_STRCASESTR@ NO_STRLCPY=@NO_STRLCPY@ NO_SETENV=@NO_SETENV@ NO_ICONV=@NO_ICONV@ - diff --git a/connect.c b/connect.c index 8cbda88dda..7fab9c0fd9 100644 --- a/connect.c +++ b/connect.c @@ -390,7 +390,7 @@ static int git_proxy_command_options(const char *var, const char *value) } if (0 <= matchlen) { /* core.gitproxy = none for kernel.org */ - if (matchlen == 4 && + if (matchlen == 4 && !memcmp(value, "none", 4)) matchlen = 0; git_proxy_command = xmalloc(matchlen + 1); diff --git a/contrib/README b/contrib/README index e1c0a01ff3..05f291c1f1 100644 --- a/contrib/README +++ b/contrib/README @@ -41,4 +41,3 @@ submit a patch to create a subdirectory of contrib/ and put your stuff there. -jc - diff --git a/contrib/blameview/README b/contrib/blameview/README index 50a6f67fd6..fada5ce909 100644 --- a/contrib/blameview/README +++ b/contrib/blameview/README @@ -7,4 +7,3 @@ To: Linus Torvalds Cc: git@vger.kernel.org Date: Sat, 27 Jan 2007 18:52:38 -0500 Message-ID: <20070127235238.GA28706@coredump.intra.peff.net> - diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview index 2d80e2bad2..3dc1ef50c7 100755 --- a/contrib/gitview/gitview +++ b/contrib/gitview/gitview @@ -1277,5 +1277,3 @@ if __name__ == "__main__": view = GitView( without_diff != 1) view.run(sys.argv[without_diff:]) - - diff --git a/contrib/hooks/post-receive-email b/contrib/hooks/post-receive-email index d1bef9125b..c589a39a0c 100644 --- a/contrib/hooks/post-receive-email +++ b/contrib/hooks/post-receive-email @@ -199,7 +199,7 @@ generate_email_footer() hooks/post-receive - -- + -- $projectdesc EOF } diff --git a/contrib/remotes2config.sh b/contrib/remotes2config.sh index dc09eae972..0c8b954490 100644 --- a/contrib/remotes2config.sh +++ b/contrib/remotes2config.sh @@ -31,5 +31,3 @@ if [ -d "$GIT_DIR"/remotes ]; then esac done fi - - diff --git a/convert-objects.c b/convert-objects.c index cefbcebdca..90e7900e6d 100644 --- a/convert-objects.c +++ b/convert-objects.c @@ -194,7 +194,7 @@ static unsigned long parse_oldstyle_date(const char *buf) fmt++; } while (*buf && *fmt); printf("left: %s\n", buf); - return mktime(&tm); + return mktime(&tm); } static int convert_date_line(char *dst, void **buf, unsigned long *sp) diff --git a/copy.c b/copy.c index d340bb253e..c225d1b0ff 100644 --- a/copy.c +++ b/copy.c @@ -34,4 +34,3 @@ int copy_fd(int ifd, int ofd) close(ifd); return 0; } - diff --git a/ctype.c b/ctype.c index 56bdffa636..ee06eb7f48 100644 --- a/ctype.c +++ b/ctype.c @@ -20,4 +20,3 @@ unsigned char sane_ctype[256] = { AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, 0, 0, 0, 0, 0, /* 112-15 */ /* Nothing in the 128.. range */ }; - diff --git a/daemon.c b/daemon.c index 674e30dca3..77792509e3 100644 --- a/daemon.c +++ b/daemon.c @@ -133,7 +133,7 @@ static int avoid_alias(char *p) { int sl, ndot; - /* + /* * This resurrects the belts and suspenders paranoia check by HPA * done in <435560F7.4080006@zytor.com> thread, now enter_repo() * does not do getcwd() based path canonicalizations. @@ -247,7 +247,7 @@ static char *path_ok(struct interp *itable) int pathlen = strlen(path); /* The validation is done on the paths after enter_repo - * appends optional {.git,.git/.git} and friends, but + * appends optional {.git,.git/.git} and friends, but * it does not use getcwd(). So if your /pub is * a symlink to /mnt/pub, you can whitelist /pub and * do not have to say /mnt/pub. diff --git a/date.c b/date.c index 4690371e55..316841e8ad 100644 --- a/date.c +++ b/date.c @@ -403,7 +403,7 @@ static int match_multi_number(unsigned long num, char c, const char *date, char } /* - * We've seen a digit. Time? Year? Date? + * We've seen a digit. Time? Year? Date? */ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt) { @@ -495,7 +495,7 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt } else if (num > 0 && num < 13) { tm->tm_mon = num-1; } - + return n; } @@ -569,13 +569,13 @@ int parse_date(const char *date, char *result, int maxlen) if (!match) { /* BAD CRAP */ match = 1; - } + } date += match; } /* mktime uses local timezone */ - then = my_mktime(&tm); + then = my_mktime(&tm); if (offset == -1) offset = (then - mktime(&tm)) / 60; @@ -691,7 +691,7 @@ static const struct typelen { { "days", 24*60*60 }, { "weeks", 7*24*60*60 }, { NULL } -}; +}; static const char *approxidate_alpha(const char *date, struct tm *tm, int *num) { diff --git a/diff-lib.c b/diff-lib.c index 07f4e8106a..7fb19c7b87 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -664,7 +664,7 @@ int run_diff_index(struct rev_info *revs, int cached) const char *tree_name; int match_missing = 0; - /* + /* * Backward compatibility wart - "diff-index -m" does * not mean "do not ignore merges", but totally different. */ diff --git a/diff.c b/diff.c index c57ac33414..cafa7debeb 100644 --- a/diff.c +++ b/diff.c @@ -3031,7 +3031,7 @@ void diff_addremove(struct diff_options *options, * entries to the diff-core. They will be prefixed * with something like '=' or '*' (I haven't decided * which but should not make any difference). - * Feeding the same new and old to diff_change() + * Feeding the same new and old to diff_change() * also has the same effect. * Before the final output happens, they are pruned after * merged into rename/copy pairs as appropriate. @@ -3058,7 +3058,7 @@ void diff_change(struct diff_options *options, unsigned old_mode, unsigned new_mode, const unsigned char *old_sha1, const unsigned char *new_sha1, - const char *base, const char *path) + const char *base, const char *path) { char concatpath[PATH_MAX]; struct diff_filespec *one, *two; diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c index c4a77d71da..af9fffe6e8 100644 --- a/diffcore-pickaxe.c +++ b/diffcore-pickaxe.c @@ -102,7 +102,7 @@ void diffcore_pickaxe(const char *needle, int opts) for (i = 0; i < q->nr; i++) diff_free_filepair(q->queue[i]); } - else + else /* Showing only the filepairs that has the needle */ for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; diff --git a/entry.c b/entry.c index ae6476496a..c540ae13e8 100644 --- a/entry.c +++ b/entry.c @@ -31,7 +31,7 @@ static void remove_subtree(const char *path) struct dirent *de; char pathbuf[PATH_MAX]; char *name; - + if (!dir) die("cannot opendir %s (%s)", path, strerror(errno)); strcpy(pathbuf, path); diff --git a/environment.c b/environment.c index 9d3e5eb72f..8b9b89d0a0 100644 --- a/environment.c +++ b/environment.c @@ -105,5 +105,3 @@ char *get_graft_file(void) setup_git_env(); return git_graft_file; } - - diff --git a/fetch-pack.c b/fetch-pack.c index aa59043c03..9c81305be5 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -114,7 +114,7 @@ static const unsigned char* get_rev(void) commit->object.flags |= POPPED; if (!(commit->object.flags & COMMON)) non_common_revs--; - + parents = commit->parents; if (commit->object.flags & COMMON) { diff --git a/fetch.c b/fetch.c index 8e29d313f8..dda33e548b 100644 --- a/fetch.c +++ b/fetch.c @@ -15,7 +15,7 @@ int get_verbosely = 0; int get_recover = 0; static unsigned char current_commit_sha1[20]; -void pull_say(const char *fmt, const char *hex) +void pull_say(const char *fmt, const char *hex) { if (get_verbosely) fprintf(stderr, fmt, hex); @@ -153,7 +153,7 @@ static int process(struct object *obj) return 0; prefetch(obj->sha1); } - + object_list_insert(obj, process_queue_end); process_queue_end = &(*process_queue_end)->next; return 0; diff --git a/git-archimport.perl b/git-archimport.perl index c1e7c1ddcb..b21077206a 100755 --- a/git-archimport.perl +++ b/git-archimport.perl @@ -3,19 +3,19 @@ # This tool is copyright (c) 2005, Martin Langhoff. # It is released under the Gnu Public License, version 2. # -# The basic idea is to walk the output of tla abrowse, -# fetch the changesets and apply them. +# The basic idea is to walk the output of tla abrowse, +# fetch the changesets and apply them. # =head1 Invocation - git-archimport [ -h ] [ -v ] [ -o ] [ -a ] [ -f ] [ -T ] - [ -D depth] [ -t tempdir ] / [ / ] + git-archimport [ -h ] [ -v ] [ -o ] [ -a ] [ -f ] [ -T ] + [ -D depth] [ -t tempdir ] / [ / ] Imports a project from one or more Arch repositories. It will follow branches and repositories within the namespaces defined by the parameters supplied. If it cannot find the remote branch a merge comes from -it will just import it as a regular commit. If it can find it, it will mark it +it will just import it as a regular commit. If it can find it, it will mark it as a merge whenever possible. See man (1) git-archimport for more details. @@ -25,14 +25,14 @@ See man (1) git-archimport for more details. - create tag objects instead of ref tags - audit shell-escaping of filenames - hide our private tags somewhere smarter - - find a way to make "cat *patches | patch" safe even when patchfiles are missing newlines + - find a way to make "cat *patches | patch" safe even when patchfiles are missing newlines - sort and apply patches by graphing ancestry relations instead of just relying in dates supplied in the changeset itself. tla ancestry-graph -m could be helpful here... =head1 Devel tricks -Add print in front of the shell commands invoked via backticks. +Add print in front of the shell commands invoked via backticks. =head1 Devel Notes @@ -126,16 +126,16 @@ sub do_abrowse { my $stage = shift; while (my ($limit, $level) = each %arch_branches) { next unless $level == $stage; - - open ABROWSE, "$TLA abrowse -fkD --merges $limit |" + + open ABROWSE, "$TLA abrowse -fkD --merges $limit |" or die "Problems with tla abrowse: $!"; - + my %ps = (); # the current one my $lastseen = ''; - + while () { chomp; - + # first record padded w 8 spaces if (s/^\s{8}\b//) { my ($id, $type) = split(m/\s+/, $_, 2); @@ -147,13 +147,13 @@ sub do_abrowse { push (@psets, \%last_ps); $psets{ $last_ps{id} } = \%last_ps; } - + my $branch = extract_versionname($id); %ps = ( id => $id, branch => $branch ); if (%last_ps && ($last_ps{branch} eq $branch)) { $ps{parent_id} = $last_ps{id}; } - + $arch_branches{$branch} = 1; $lastseen = 'id'; @@ -166,16 +166,16 @@ sub do_abrowse { $ps{type} = 't'; # read which revision we've tagged when we parse the log $ps{tag} = $1; - } else { + } else { warn "Unknown type $type"; } $arch_branches{$branch} = 1; $lastseen = 'id'; - } elsif (s/^\s{10}//) { - # 10 leading spaces or more + } elsif (s/^\s{10}//) { + # 10 leading spaces or more # indicate commit metadata - + # date if ($lastseen eq 'id' && m/^(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d)/){ $ps{date} = $1; @@ -186,12 +186,12 @@ sub do_abrowse { } elsif ($lastseen eq 'merges' && s/^\s{2}//) { my $id = $_; push (@{$ps{merges}}, $id); - + # aggressive branch finding: if ($opt_D) { my $branch = extract_versionname($id); my $repo = extract_reponame($branch); - + if (archive_reachable($repo) && !defined $arch_branches{$branch}) { $arch_branches{$branch} = $stage + 1; @@ -208,10 +208,10 @@ sub do_abrowse { if (@psets && $psets[$#psets]{branch} eq $ps{branch}) { $temp{parent_id} = $psets[$#psets]{id}; } - push (@psets, \%temp); + push (@psets, \%temp); $psets{ $temp{id} } = \%temp; - } - + } + close ABROWSE or die "$TLA abrowse failed on $limit\n"; } } # end foreach $root @@ -253,7 +253,7 @@ unless (-d $git_dir) { # initial import while (my $file = readdir(DIR)) { # skip non-interesting-files next unless -f "$ptag_dir/$file"; - + # convert first '--' to '/' from old git-archimport to use # as an archivename/c--b--v private tag if ($file !~ m!,!) { @@ -275,7 +275,7 @@ sub extract_reponame { my $fq_cvbr = shift; # archivename/[[[[category]branch]version]revision] return (split(/\//, $fq_cvbr))[0]; } - + sub extract_versionname { my $name = shift; $name =~ s/--(?:patch|version(?:fix)?|base)-\d+$//; @@ -283,7 +283,7 @@ sub extract_versionname { } # convert a fully-qualified revision or version to a unique dirname: -# normalperson@yhbt.net-05/mpd--uclinux--1--patch-2 +# normalperson@yhbt.net-05/mpd--uclinux--1--patch-2 # becomes: normalperson@yhbt.net-05,mpd--uclinux--1 # # the git notion of a branch is closer to @@ -339,7 +339,7 @@ sub git_branchname { sub process_patchset_accurate { my $ps = shift; - + # switch to that branch if we're not already in that branch: if (-e "$git_dir/refs/heads/$ps->{branch}") { system('git-checkout','-f',$ps->{branch}) == 0 or die "$! $?\n"; @@ -348,7 +348,7 @@ sub process_patchset_accurate { my $rm = safe_pipe_capture('git-ls-files','--others','-z'); rmtree(split(/\0/,$rm)) if $rm; } - + # Apply the import/changeset/merge into the working tree my $dir = sync_to_ps($ps); # read the new log entry: @@ -361,9 +361,9 @@ sub process_patchset_accurate { parselog($ps, \@commitlog); if ($ps->{id} =~ /--base-0$/ && $ps->{id} ne $psets[0]{id}) { - # this should work when importing continuations + # this should work when importing continuations if ($ps->{tag} && (my $branchpoint = eval { ptag($ps->{tag}) })) { - + # find where we are supposed to branch from if (! -e "$git_dir/refs/heads/$ps->{branch}") { system('git-branch',$ps->{branch},$branchpoint) == 0 or die "$! $?\n"; @@ -388,8 +388,8 @@ sub process_patchset_accurate { } # allow multiple bases/imports here since Arch supports cherry-picks # from unrelated trees - } - + } + # update the index with all the changes we got system('git-diff-files --name-only -z | '. 'git-update-index --remove -z --stdin') == 0 or die "$! $?\n"; @@ -402,7 +402,7 @@ sub process_patchset_accurate { # does not handle permissions or any renames involving directories sub process_patchset_fast { my $ps = shift; - # + # # create the branch if needed # if ($ps->{type} eq 'i' && !$import) { @@ -417,9 +417,9 @@ sub process_patchset_fast { # new branch! we need to verify a few things die "Branch on a non-tag!" unless $ps->{type} eq 't'; my $branchpoint = ptag($ps->{tag}); - die "Tagging from unknown id unsupported: $ps->{tag}" + die "Tagging from unknown id unsupported: $ps->{tag}" unless $branchpoint; - + # find where we are supposed to branch from if (! -e "$git_dir/refs/heads/$ps->{branch}") { system('git-branch',$ps->{branch},$branchpoint) == 0 or die "$! $?\n"; @@ -435,13 +435,13 @@ sub process_patchset_fast { } system('git-checkout',$ps->{branch}) == 0 or die "$! $?\n"; return 0; - } + } die $! if $?; - } + } # # Apply the import/changeset/merge into the working tree - # + # if ($ps->{type} eq 'i' || $ps->{type} eq 't') { apply_import($ps) or die $!; $stats{import_or_tag}++; @@ -455,10 +455,10 @@ sub process_patchset_fast { # prepare update git's index, based on what arch knows # about the pset, resolve parents, etc # - - my @commitlog = safe_pipe_capture($TLA,'cat-archive-log',$ps->{id}); + + my @commitlog = safe_pipe_capture($TLA,'cat-archive-log',$ps->{id}); die "Error in cat-archive-log: $!" if $?; - + parselog($ps,\@commitlog); # imports don't give us good info @@ -485,10 +485,10 @@ sub process_patchset_fast { if (@$ren % 2) { die "Odd number of entries in rename!?"; } - + while (@$ren) { my $from = shift @$ren; - my $to = shift @$ren; + my $to = shift @$ren; unless (-d dirname($to)) { mkpath(dirname($to)); # will die on err @@ -529,20 +529,20 @@ if ($opt_f) { "Things may be a bit slow\n"; *process_patchset = *process_patchset_accurate; } - + foreach my $ps (@psets) { # process patchsets $ps->{branch} = git_branchname($ps->{id}); # - # ensure we have a clean state - # + # ensure we have a clean state + # if (my $dirty = `git-diff-files`) { die "Unclean tree when about to process $ps->{id} " . " - did we fail to commit cleanly before?\n$dirty"; } die $! if $?; - + # # skip commits already in repo # @@ -559,7 +559,7 @@ foreach my $ps (@psets) { my $tree = `git-write-tree`; die "cannot write tree $!" if $?; chomp $tree; - + # # Who's your daddy? # @@ -570,18 +570,18 @@ foreach my $ps (@psets) { close HEAD; chomp $p; push @par, '-p', $p; - } else { + } else { if ($ps->{type} eq 's') { warn "Could not find the right head for the branch $ps->{branch}"; } } } - + if ($ps->{merges}) { push @par, find_parents($ps); } - # + # # Commit, tag and clean state # $ENV{TZ} = 'GMT'; @@ -592,14 +592,14 @@ foreach my $ps (@psets) { $ENV{GIT_COMMITTER_EMAIL} = $ps->{email}; $ENV{GIT_COMMITTER_DATE} = $ps->{date}; - my $pid = open2(*READER, *WRITER,'git-commit-tree',$tree,@par) + my $pid = open2(*READER, *WRITER,'git-commit-tree',$tree,@par) or die $!; print WRITER $ps->{summary},"\n\n"; print WRITER $ps->{message},"\n"; - + # make it easy to backtrack and figure out which Arch revision this was: print WRITER 'git-archimport-id: ',$ps->{id},"\n"; - + close WRITER; my $commitid = ; # read chomp $commitid; @@ -611,7 +611,7 @@ foreach my $ps (@psets) { } # # Update the branch - # + # open HEAD, ">","$git_dir/refs/heads/$ps->{branch}"; print HEAD $commitid; close HEAD; @@ -640,7 +640,7 @@ exit 0; sub sync_to_ps { my $ps = shift; my $tree_dir = $tmp.'/'.tree_dirname($ps->{id}); - + $opt_v && print "sync_to_ps($ps->{id}) method: "; if (-d $tree_dir) { @@ -674,7 +674,7 @@ sub sync_to_ps { safe_pipe_capture($TLA,'get','--no-pristine',$ps->{id},$tree_dir); $stats{get_new}++; } - + # added -I flag to rsync since we're going to fast! AIEEEEE!!!! system('rsync','-aI','--delete','--exclude',$git_dir, # '--exclude','.arch-inventory', @@ -691,15 +691,15 @@ sub apply_import { mkpath($tmp); safe_pipe_capture($TLA,'get','-s','--no-pristine',$ps->{id},"$tmp/import"); - die "Cannot get import: $!" if $?; + die "Cannot get import: $!" if $?; system('rsync','-aI','--delete', '--exclude',$git_dir, '--exclude','.arch-ids','--exclude','{arch}', "$tmp/import/", './'); die "Cannot rsync import:$!" if $?; - + rmtree("$tmp/import"); die "Cannot remove tempdir: $!" if $?; - + return 1; } @@ -712,13 +712,13 @@ sub apply_cset { # get the changeset safe_pipe_capture($TLA,'get-changeset',$ps->{id},"$tmp/changeset"); die "Cannot get changeset: $!" if $?; - + # apply patches if (`find $tmp/changeset/patches -type f -name '*.patch'`) { # this can be sped up considerably by doing # (find | xargs cat) | patch # but that can get mucked up by patches - # with missing trailing newlines or the standard + # with missing trailing newlines or the standard # 'missing newline' flag in the patch - possibly # produced with an old/buggy diff. # slow and safe, we invoke patch once per patchfile @@ -741,7 +741,7 @@ sub apply_cset { # bring in new files system('rsync','-aI','--exclude',$git_dir, - '--exclude','.arch-ids', + '--exclude','.arch-ids', '--exclude', '{arch}', "$tmp/changeset/new-files-archive/",'./'); @@ -789,7 +789,7 @@ sub parselog { removed_files => 1, removed_directories => 1, ); - + chomp (@$log); while ($_ = shift @$log) { if (/^Continuation-of:\s*(.*)/) { @@ -828,7 +828,7 @@ sub parselog { } } } - + # drop leading empty lines from the log message while (@$log && $log->[0] eq '') { shift @$log; @@ -842,7 +842,7 @@ sub parselog { $ps->{summary} = $log->[0] . '...'; } $ps->{message} = join("\n",@$log); - + # skip Arch control files, unescape pika-escaped files foreach my $k (keys %want_headers) { next unless (defined $ps->{$k}); @@ -867,7 +867,7 @@ sub parselog { # write/read a tag sub tag { my ($tag, $commit) = @_; - + if ($opt_o) { $tag =~ s|/|--|g; } else { @@ -875,7 +875,7 @@ sub tag { $patchname =~ s/.*--//; $tag = git_branchname ($tag) . '--' . $patchname; } - + if ($commit) { open(C,">","$git_dir/refs/tags/$tag") or die "Cannot create tag $tag: $!\n"; @@ -902,8 +902,8 @@ sub ptag { my ($tag, $commit) = @_; # don't use subdirs for tags yet, it could screw up other porcelains - $tag =~ s|/|,|g; - + $tag =~ s|/|,|g; + my $tag_file = "$ptag_dir/$tag"; my $tag_branch_dir = dirname($tag_file); mkpath($tag_branch_dir) unless (-d $tag_branch_dir); @@ -915,7 +915,7 @@ sub ptag { or die "Cannot write tag $tag: $!\n"; close(C) or die "Cannot write tag $tag: $!\n"; - $rptags{$commit} = $tag + $rptags{$commit} = $tag unless $tag =~ m/--base-0$/; } else { # read # if the tag isn't there, return 0 @@ -941,7 +941,7 @@ sub find_parents { # Identify what branches are merging into me # and whether we are fully merged # git-merge-base should tell - # me what the base of the merge should be + # me what the base of the merge should be # my $ps = shift; @@ -963,14 +963,14 @@ sub find_parents { } # - # foreach branch find a merge base and walk it to the + # foreach branch find a merge base and walk it to the # head where we are, collecting the merged patchsets that # Arch has recorded. Keep that in @have # Compare that with the commits on the other branch # between merge-base and the tip of the branch (@need) # and see if we have a series of consecutive patches # starting from the merge base. The tip of the series - # of consecutive patches merged is our new parent for + # of consecutive patches merged is our new parent for # that branch. # foreach my $branch (keys %branches) { @@ -979,13 +979,13 @@ sub find_parents { next unless -e "$git_dir/refs/heads/$branch"; my $mergebase = `git-merge-base $branch $ps->{branch}`; - if ($?) { - # Don't die here, Arch supports one-way cherry-picking - # between branches with no common base (or any relationship - # at all beforehand) - warn "Cannot find merge base for $branch and $ps->{branch}"; - next; - } + if ($?) { + # Don't die here, Arch supports one-way cherry-picking + # between branches with no common base (or any relationship + # at all beforehand) + warn "Cannot find merge base for $branch and $ps->{branch}"; + next; + } chomp $mergebase; # now walk up to the mergepoint collecting what patches we have @@ -1010,7 +1010,7 @@ sub find_parents { # merge what we have with what ancestors have %have = (%have, %ancestorshave); - # see what the remote branch has - these are the merges we + # see what the remote branch has - these are the merges we # will want to have in a consecutive series from the mergebase my $otherbranchtip = git_rev_parse($branch); my @needraw = `git-rev-list --topo-order $otherbranchtip ^$mergebase`; @@ -1018,7 +1018,7 @@ sub find_parents { foreach my $needps (@needraw) { # get the psets $needps = commitid2pset($needps); # git-rev-list will also - # list commits merged in via earlier + # list commits merged in via earlier # merges. we are only interested in commits # from the branch we're looking at if ($branch eq $needps->{branch}) { @@ -1054,7 +1054,7 @@ sub find_parents { next unless ref $psets{$p}{merges}; my @merges = @{$psets{$p}{merges}}; foreach my $merge (@merges) { - if ($parents{$merge}) { + if ($parents{$merge}) { delete $parents{$merge}; } } @@ -1079,10 +1079,10 @@ sub git_rev_parse { sub commitid2pset { my $commitid = shift; chomp $commitid; - my $name = $rptags{$commitid} + my $name = $rptags{$commitid} || die "Cannot find reverse tag mapping for $commitid"; $name =~ s|,|/|; - my $ps = $psets{$name} + my $ps = $psets{$name} || (print Dumper(sort keys %psets)) && die "Cannot find patchset for $name"; return $ps; } @@ -1112,7 +1112,7 @@ sub archive_reachable { my $archive = shift; return 1 if $reachable{$archive}; return 0 if $unreachable{$archive}; - + if (system "$TLA whereis-archive $archive >/dev/null") { if ($opt_a && (system($TLA,'register-archive', "http://mirrors.sourcecontrol.net/$archive") == 0)) { @@ -1127,4 +1127,3 @@ sub archive_reachable { return 1; } } - diff --git a/git-checkout.sh b/git-checkout.sh index 6b6facfd5a..d561c88dcb 100755 --- a/git-checkout.sh +++ b/git-checkout.sh @@ -210,7 +210,7 @@ else esac # Match the index to the working tree, and do a three-way. - git diff-files --name-only | git update-index --remove --stdin && + git diff-files --name-only | git update-index --remove --stdin && work=`git write-tree` && git read-tree $v --reset -u $new || exit @@ -245,7 +245,7 @@ else (exit $saved_err) fi -# +# # Switch the HEAD pointer to the new branch if we # checked out a branch head, and remove any potential # old MERGE_HEAD's (subsequent commits will clearly not diff --git a/git-clone.sh b/git-clone.sh index fdd354f2da..5bfd8d1556 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -2,7 +2,7 @@ # # Copyright (c) 2005, Linus Torvalds # Copyright (c) 2005, Junio C Hamano -# +# # Clone a repository into a different directory that does not yet exist. # See git-sh-setup why. @@ -98,7 +98,7 @@ while *,--na|*,--nak|*,--nake|*,--naked|\ *,-b|*,--b|*,--ba|*,--bar|*,--bare) bare=yes ;; *,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local) use_local=yes ;; - *,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared) + *,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared) local_shared=yes; use_local=yes ;; 1,--template) usage ;; *,--template) @@ -410,4 +410,3 @@ fi rm -f "$GIT_DIR/CLONE_HEAD" "$GIT_DIR/REMOTE_HEAD" trap - 0 - diff --git a/git-commit.sh b/git-commit.sh index e8b60f7049..5547a02954 100755 --- a/git-commit.sh +++ b/git-commit.sh @@ -557,7 +557,7 @@ then } >>"$GIT_DIR"/COMMIT_EDITMSG else # we need to check if there is anything to commit - run_status >/dev/null + run_status >/dev/null fi if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" -a -z "$amend" ] then diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl index 42060ef6e1..e9832d2bb9 100755 --- a/git-cvsexportcommit.perl +++ b/git-cvsexportcommit.perl @@ -197,7 +197,7 @@ if (@canstatusfiles) { # ... validate new files, foreach my $f (@afiles) { if (defined ($cvsstat{$f}) and $cvsstat{$f} ne "Unknown") { - $dirty = 1; + $dirty = 1; warn "File $f is already known in your CVS checkout -- perhaps it has been added by another user. Or this may indicate that it exists on a different branch. If this is the case, use -f to force the merge.\n"; warn "Status was: $cvsstat{$f}\n"; } diff --git a/git-cvsimport.perl b/git-cvsimport.perl index 4e6c9c6cc7..3225a2a25d 100755 --- a/git-cvsimport.perl +++ b/git-cvsimport.perl @@ -145,7 +145,7 @@ my $cvs_tree; if ($#ARGV == 0) { $cvs_tree = $ARGV[0]; } elsif (-f 'CVS/Repository') { - open my $f, '<', 'CVS/Repository' or + open my $f, '<', 'CVS/Repository' or die 'Failed to open CVS/Repository'; $cvs_tree = <$f>; chomp $cvs_tree; @@ -434,7 +434,7 @@ sub file { my ($self,$fn,$rev) = @_; my $res; - my ($fh, $name) = tempfile('gitcvs.XXXXXX', + my ($fh, $name) = tempfile('gitcvs.XXXXXX', DIR => File::Spec->tmpdir(), UNLINK => 1); $self->_file($fn,$rev) and $res = $self->_line($fh); @@ -520,8 +520,8 @@ sub is_sha1 { sub get_headref ($$) { my $name = shift; - my $git_dir = shift; - + my $git_dir = shift; + my $f = "$git_dir/refs/heads/$name"; if (open(my $fh, $f)) { chomp(my $r = <$fh>); @@ -771,7 +771,7 @@ sub commit { $xtag =~ s/\s+\*\*.*$//; # Remove stuff like ** INVALID ** and ** FUNKY ** $xtag =~ tr/_/\./ if ( $opt_u ); $xtag =~ s/[\/]/$opt_s/g; - + my $pid = open2($in, $out, 'git-mktag'); print $out "object $cid\n". "type commit\n". @@ -788,7 +788,7 @@ sub commit { $? != 0 or $tagobj !~ /^[0123456789abcdef]{40}$/ ) { die "Cannot create tag object $xtag: $!\n"; } - + open(C,">$git_dir/refs/tags/$xtag") or die "Cannot create tag $xtag: $!\n"; diff --git a/git-gui/GIT-VERSION-GEN b/git-gui/GIT-VERSION-GEN index 25647c8060..eee495a986 100755 --- a/git-gui/GIT-VERSION-GEN +++ b/git-gui/GIT-VERSION-GEN @@ -78,5 +78,3 @@ test "$VN" = "$VC" || { echo >&2 "GITGUI_VERSION = $VN" echo "GITGUI_VERSION = $VN" >$GVF } - - diff --git a/git-gui/lib/class.tcl b/git-gui/lib/class.tcl index 88b056522a..72494c1a1e 100644 --- a/git-gui/lib/class.tcl +++ b/git-gui/lib/class.tcl @@ -151,4 +151,3 @@ auto_mkindex_parser::command constructor {name args} { [format { [list source [file join $dir %s]]} \ [file split $scriptFile]] "\n" } - diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh index 7d62d7902c..254d210bdc 100755 --- a/git-merge-one-file.sh +++ b/git-merge-one-file.sh @@ -88,7 +88,7 @@ case "${1:-.}${2:-.}${3:-.}" in # remove lines that are unique to ours. orig=`git-unpack-file $2` sz0=`wc -c <"$orig"` - diff -u -La/$orig -Lb/$orig $orig $src2 | git-apply --no-add + diff -u -La/$orig -Lb/$orig $orig $src2 | git-apply --no-add sz1=`wc -c <"$orig"` # If we do not have enough common material, it is not diff --git a/git-p4import.py b/git-p4import.py index 60a758bfe3..0f3d97b67e 100644 --- a/git-p4import.py +++ b/git-p4import.py @@ -358,4 +358,3 @@ for id in changes: if stitch == 1: git.clean_directories() stitch = 0 - diff --git a/git-svnimport.perl b/git-svnimport.perl index 3af8c7e110..f4597626b9 100755 --- a/git-svnimport.perl +++ b/git-svnimport.perl @@ -542,7 +542,7 @@ sub copy_path($$$$$$$$) { if ($node_kind eq $SVN::Node::dir) { $srcpath =~ s#/*$#/#; } - + my $pid = open my $f,'-|'; die $! unless defined $pid; if (!$pid) { @@ -560,7 +560,7 @@ sub copy_path($$$$$$$$) { } else { $p = $path; } - push(@$new,[$mode,$sha1,$p]); + push(@$new,[$mode,$sha1,$p]); } close($f) or print STDERR "$newrev:$newbranch: could not list files in $oldpath \@ $rev\n"; diff --git a/git-tag.sh b/git-tag.sh index 37cee978d2..c84043902f 100755 --- a/git-tag.sh +++ b/git-tag.sh @@ -64,7 +64,7 @@ do done ;; -m) - annotate=1 + annotate=1 shift message="$1" if test "$#" = "0"; then @@ -90,7 +90,7 @@ do username="$1" ;; -d) - shift + shift had_error=0 for tag do @@ -180,4 +180,3 @@ if [ "$annotate" ]; then fi git update-ref "refs/tags/$name" "$object" "$prev" - diff --git a/git-verify-tag.sh b/git-verify-tag.sh index 8db7dd0b7d..f2d5597dba 100755 --- a/git-verify-tag.sh +++ b/git-verify-tag.sh @@ -42,4 +42,3 @@ cat "$GIT_DIR/.tmp-vtag" | sed '/-----BEGIN PGP/Q' | gpg --verify "$GIT_DIR/.tmp-vtag" - || exit 1 rm -f "$GIT_DIR/.tmp-vtag" - diff --git a/git.spec.in b/git.spec.in index 3a45eb8761..b9dc1d59eb 100644 --- a/git.spec.in +++ b/git.spec.in @@ -63,7 +63,7 @@ Git tools for importing Perforce repositories. %package email Summary: Git tools for sending email Group: Development/Tools -Requires: git-core = %{version}-%{release} +Requires: git-core = %{version}-%{release} %description email Git tools for sending email. diff --git a/gitk b/gitk index a57e84cef7..87c3690ff3 100755 --- a/gitk +++ b/gitk @@ -337,7 +337,7 @@ proc readrefs {} { set tagids($name) $commit lappend idtags($commit) $name } - } + } catch { set tagcontents($name) [exec git cat-file tag $id] } diff --git a/gitweb/README b/gitweb/README index e02e90f042..7186cede2f 100644 --- a/gitweb/README +++ b/gitweb/README @@ -79,4 +79,3 @@ Originally written by: Any comment/question/concern to: Git mailing list - diff --git a/help.c b/help.c index 6a9af4d175..1cd33ece6b 100644 --- a/help.c +++ b/help.c @@ -219,5 +219,3 @@ int cmd_help(int argc, const char **argv, const char *prefix) return 0; } - - diff --git a/http-fetch.c b/http-fetch.c index 09baedc18a..202fae0ba8 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -828,7 +828,7 @@ static void abort_object_request(struct object_request *obj_req) } unlink(obj_req->tmpfile); if (obj_req->slot) { - release_active_slot(obj_req->slot); + release_active_slot(obj_req->slot); obj_req->slot = NULL; } release_object_request(obj_req); diff --git a/http-push.c b/http-push.c index 79d2c38608..7c3720f602 100644 --- a/http-push.c +++ b/http-push.c @@ -518,7 +518,7 @@ static void start_put(struct transfer_request *request) request->buffer.size = stream.total_out; request->buffer.posn = 0; - request->url = xmalloc(strlen(remote->url) + + request->url = xmalloc(strlen(remote->url) + strlen(request->lock->token) + 51); strcpy(request->url, remote->url); posn = request->url + strlen(remote->url); diff --git a/http.c b/http.c index ae27e0c940..c6fb8ace9f 100644 --- a/http.c +++ b/http.c @@ -137,7 +137,7 @@ static int http_options(const char *var, const char *value) return 0; } -#ifdef USE_CURL_MULTI +#ifdef USE_CURL_MULTI if (!strcmp("http.maxrequests", var)) { if (max_requests == -1) max_requests = git_config_int(var, value); diff --git a/imap-send.c b/imap-send.c index 4283a4acda..a5a0696084 100644 --- a/imap-send.c +++ b/imap-send.c @@ -1239,7 +1239,7 @@ split_msg( msg_data_t *all_msgs, msg_data_t *msg, int *ofs ) msg->data[ msg->len ] = 0; *ofs += msg->len; - return 1; + return 1; } static imap_server_conf_t server = diff --git a/local-fetch.c b/local-fetch.c index 4b650efa8b..bf7ec6c2a3 100644 --- a/local-fetch.c +++ b/local-fetch.c @@ -114,7 +114,7 @@ static int fetch_pack(const unsigned char *sha1) return -1; target = find_sha1_pack(sha1, packs); if (!target) - return error("Couldn't find %s: not separate or in any pack", + return error("Couldn't find %s: not separate or in any pack", sha1_to_hex(sha1)); if (get_verbosely) { fprintf(stderr, "Getting pack %s\n", @@ -122,11 +122,11 @@ static int fetch_pack(const unsigned char *sha1) fprintf(stderr, " which contains %s\n", sha1_to_hex(sha1)); } - sprintf(filename, "%s/objects/pack/pack-%s.pack", + sprintf(filename, "%s/objects/pack/pack-%s.pack", path, sha1_to_hex(target->sha1)); copy_file(filename, sha1_pack_name(target->sha1), sha1_to_hex(target->sha1), 1); - sprintf(filename, "%s/objects/pack/pack-%s.idx", + sprintf(filename, "%s/objects/pack/pack-%s.idx", path, sha1_to_hex(target->sha1)); copy_file(filename, sha1_pack_index_name(target->sha1), sha1_to_hex(target->sha1), 1); @@ -141,7 +141,7 @@ static int fetch_file(const unsigned char *sha1) char *hex = sha1_to_hex(sha1); char *dest_filename = sha1_file_name(sha1); - if (object_name_start < 0) { + if (object_name_start < 0) { strcpy(filename, path); /* e.g. git.git */ strcat(filename, "/objects/"); object_name_start = strlen(filename); diff --git a/lockfile.c b/lockfile.c index 23db35aff2..5ad2858b48 100644 --- a/lockfile.c +++ b/lockfile.c @@ -97,4 +97,3 @@ void rollback_lock_file(struct lock_file *lk) unlink(lk->filename); lk->filename[0] = 0; } - diff --git a/mailmap.c b/mailmap.c index cb567a2832..8714167059 100644 --- a/mailmap.c +++ b/mailmap.c @@ -89,4 +89,3 @@ int map_email(struct path_list *map, const char *email, char *name, int maxlen) } return 0; } - diff --git a/match-trees.c b/match-trees.c index 23cafe47b4..d7e29c4d1d 100644 --- a/match-trees.c +++ b/match-trees.c @@ -301,4 +301,3 @@ void shift_tree(const unsigned char *hash1, splice_tree(hash1, add_prefix, hash2, shifted); } - diff --git a/merge-index.c b/merge-index.c index 5599fd321b..fa719cb0b1 100644 --- a/merge-index.c +++ b/merge-index.c @@ -25,7 +25,7 @@ static void run_program(void) static int merge_entry(int pos, const char *path) { int found; - + if (pos >= active_nr) die("git-merge-index: %s not in the cache", path); arguments[0] = pgm; diff --git a/mktag.c b/mktag.c index 931011121e..070bc96c0d 100644 --- a/mktag.c +++ b/mktag.c @@ -11,7 +11,7 @@ * The first three lines are guaranteed to be at least 63 bytes: * "object \n" is 48 bytes, "type tag\n" at 9 bytes is the * shortest possible type-line, and "tag .\n" at 6 bytes is the - * shortest single-character-tag line. + * shortest single-character-tag line. * * We also artificially limit the size of the full object to 8kB. * Just because I'm a lazy bastard, and if you can't fit a signature diff --git a/mozilla-sha1/sha1.c b/mozilla-sha1/sha1.c index 847531d19f..3f06b83567 100644 --- a/mozilla-sha1/sha1.c +++ b/mozilla-sha1/sha1.c @@ -1,29 +1,29 @@ -/* +/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ - * + * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. - * + * * The Original Code is SHA 180-1 Reference Implementation (Compact version) - * + * * The Initial Developer of the Original Code is Paul Kocher of - * Cryptography Research. Portions created by Paul Kocher are + * Cryptography Research. Portions created by Paul Kocher are * Copyright (C) 1995-9 by Cryptography Research, Inc. All * Rights Reserved. - * + * * Contributor(s): * * Paul Kocher - * + * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your + * "GPL"), in which case the provisions of the GPL are applicable + * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and @@ -149,4 +149,3 @@ static void shaHashBlock(SHA_CTX *ctx) { ctx->H[3] += D; ctx->H[4] += E; } - diff --git a/mozilla-sha1/sha1.h b/mozilla-sha1/sha1.h index 5d82afa3bd..16f2d3d43c 100644 --- a/mozilla-sha1/sha1.h +++ b/mozilla-sha1/sha1.h @@ -1,29 +1,29 @@ -/* +/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ - * + * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. - * + * * The Original Code is SHA 180-1 Header File - * + * * The Initial Developer of the Original Code is Paul Kocher of - * Cryptography Research. Portions created by Paul Kocher are + * Cryptography Research. Portions created by Paul Kocher are * Copyright (C) 1995-9 by Cryptography Research, Inc. All * Rights Reserved. - * + * * Contributor(s): * * Paul Kocher - * + * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your + * "GPL"), in which case the provisions of the GPL are applicable + * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and diff --git a/object-refs.c b/object-refs.c index 022e8d841c..5345671569 100644 --- a/object-refs.c +++ b/object-refs.c @@ -85,5 +85,3 @@ void mark_reachable(struct object *obj, unsigned int mask) mark_reachable(refs->ref[i], mask); } } - - diff --git a/object.h b/object.h index 94f19eed86..397bbfa090 100644 --- a/object.h +++ b/object.h @@ -66,7 +66,7 @@ void set_object_refs(struct object *obj, struct object_refs *refs); void mark_reachable(struct object *obj, unsigned int mask); -struct object_list *object_list_insert(struct object *item, +struct object_list *object_list_insert(struct object *item, struct object_list **list_p); void object_list_append(struct object *item, diff --git a/pack-redundant.c b/pack-redundant.c index 6bc3bdf3f4..f5cd0ac59e 100644 --- a/pack-redundant.c +++ b/pack-redundant.c @@ -81,7 +81,7 @@ static struct llist * llist_copy(struct llist *list) { struct llist *ret; struct llist_item *new, *old, *prev; - + llist_init(&ret); if ((ret->size = list->size) == 0) @@ -100,7 +100,7 @@ static struct llist * llist_copy(struct llist *list) } new->next = NULL; ret->back = new; - + return ret; } diff --git a/patch-id.c b/patch-id.c index 086d2d9c68..9349bc5580 100644 --- a/patch-id.c +++ b/patch-id.c @@ -81,4 +81,4 @@ int main(int argc, char **argv) generate_id_list(); return 0; -} +} diff --git a/path-list.c b/path-list.c index caaa5cc57b..dcb4b3ac13 100644 --- a/path-list.c +++ b/path-list.c @@ -100,4 +100,3 @@ void print_path_list(const char *text, const struct path_list *p) for (i = 0; i < p->nr; i++) printf("%s:%p\n", p->items[i].path, p->items[i].util); } - diff --git a/perl/Makefile b/perl/Makefile index 0d695fd2f3..5e079ad011 100644 --- a/perl/Makefile +++ b/perl/Makefile @@ -40,4 +40,3 @@ endif # (even though GIT-CFLAGS aren't used yet. If ever) ../GIT-CFLAGS: $(MAKE) -C .. GIT-CFLAGS - diff --git a/pkt-line.c b/pkt-line.c index b60526869a..355546a1ad 100644 --- a/pkt-line.c +++ b/pkt-line.c @@ -5,7 +5,7 @@ * Write a packetized stream, where each line is preceded by * its length (including the header) as a 4-byte hex number. * A length of 'zero' means end of stream (and a length of 1-3 - * would be an error). + * would be an error). * * This is all pretty stupid, but we use this packetized line * format to make a streaming format possible without ever diff --git a/ppc/sha1.c b/ppc/sha1.c index 0820398b00..738e36c1e8 100644 --- a/ppc/sha1.c +++ b/ppc/sha1.c @@ -50,7 +50,7 @@ int SHA1_Update(SHA_CTX *c, const void *ptr, unsigned long n) p += nb; } return 0; -} +} int SHA1_Final(unsigned char *hash, SHA_CTX *c) { diff --git a/read-cache.c b/read-cache.c index ad4e187537..4362b11f47 100644 --- a/read-cache.c +++ b/read-cache.c @@ -166,7 +166,7 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st) changed |= MTIME_CHANGED; if (ce->ce_ctime.nsec != htonl(st->st_ctim.tv_nsec)) changed |= CTIME_CHANGED; -#endif +#endif if (ce->ce_uid != htonl(st->st_uid) || ce->ce_gid != htonl(st->st_gid)) @@ -597,7 +597,7 @@ static int has_dir_name(struct index_state *istate, * is being added, or we already have path and path/file is being * added. Either one would result in a nonsense tree that has path * twice when git-write-tree tries to write it out. Prevent it. - * + * * If ok-to-replace is specified, we remove the conflicting entries * from the cache so the caller should recompute the insert position. * When this happens, we return non-zero. @@ -970,8 +970,8 @@ static int ce_write(SHA_CTX *context, int fd, void *data, unsigned int len) write_buffer_len = buffered; len -= partial; data = (char *) data + partial; - } - return 0; + } + return 0; } static int write_index_ext_header(SHA_CTX *context, int fd, @@ -1037,7 +1037,7 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce) * size to zero here, then the object name recorded * in index is the 6-byte file but the cached stat information * becomes zero --- which would then match what we would - * obtain from the filesystem next time we stat("frotz"). + * obtain from the filesystem next time we stat("frotz"). * * However, the second update-index, before calling * this function, notices that the cached size is 6 diff --git a/rsh.h b/rsh.h index 3b4194239d..ee2f499291 100644 --- a/rsh.h +++ b/rsh.h @@ -1,7 +1,7 @@ #ifndef RSH_H #define RSH_H -int setup_connection(int *fd_in, int *fd_out, const char *remote_prog, +int setup_connection(int *fd_in, int *fd_out, const char *remote_prog, char *url, int rmt_argc, char **rmt_argv); #endif diff --git a/setup.c b/setup.c index a45ea8309a..14f62c42e3 100644 --- a/setup.c +++ b/setup.c @@ -39,7 +39,7 @@ const char *prefix_path(const char *prefix, int len, const char *path) if (len) { int speclen = strlen(path); char *n = xmalloc(speclen + len + 1); - + memcpy(n, prefix, len); memcpy(n + len, path, speclen+1); path = n; @@ -47,7 +47,7 @@ const char *prefix_path(const char *prefix, int len, const char *path) return path; } -/* +/* * Unlike prefix_path, this should be used if the named file does * not have to interact with index entry; i.e. name of a random file * on the filesystem. diff --git a/sha1_file.c b/sha1_file.c index 30bcd46ceb..2b860868f5 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -193,7 +193,7 @@ char *sha1_pack_name(const unsigned char *sha1) *buf++ = hex[val >> 4]; *buf++ = hex[val & 0xf]; } - + return base; } @@ -218,7 +218,7 @@ char *sha1_pack_index_name(const unsigned char *sha1) *buf++ = hex[val >> 4]; *buf++ = hex[val & 0xf]; } - + return base; } @@ -1139,7 +1139,7 @@ static int parse_sha1_header(const char *hdr, unsigned long *sizep) unsigned long size; /* - * The type can be at most ten bytes (including the + * The type can be at most ten bytes (including the * terminating '\0' that we add), and is followed by * a space. */ @@ -1738,7 +1738,7 @@ static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, cons return 0; } -struct packed_git *find_sha1_pack(const unsigned char *sha1, +struct packed_git *find_sha1_pack(const unsigned char *sha1, struct packed_git *packs) { struct packed_git *p; diff --git a/shallow.c b/shallow.c index d17868929c..dbd9f5ad0a 100644 --- a/shallow.c +++ b/shallow.c @@ -101,4 +101,3 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth, return result; } - diff --git a/ssh-upload.c b/ssh-upload.c index 498d41e19b..20c35f03dd 100644 --- a/ssh-upload.c +++ b/ssh-upload.c @@ -29,24 +29,24 @@ static int serve_object(int fd_in, int fd_out) { } if (!size) return -1; - + if (verbose) fprintf(stderr, "Serving %s\n", sha1_to_hex(sha1)); remote = 0; - + if (!has_sha1_file(sha1)) { fprintf(stderr, "git-ssh-upload: could not find %s\n", sha1_to_hex(sha1)); remote = -1; } - + if (write_in_full(fd_out, &remote, 1) != 1) return 0; - + if (remote < 0) return 0; - + return write_sha1_to_fd(fd_out, sha1); } diff --git a/strbuf.c b/strbuf.c index 7f14b0fb59..e33d06b87c 100644 --- a/strbuf.c +++ b/strbuf.c @@ -39,4 +39,3 @@ void read_line(struct strbuf *sb, FILE *fp, int term) { sb->eof = 1; strbuf_end(sb); } - diff --git a/t/Makefile b/t/Makefile index 19e38508a7..b25caca887 100644 --- a/t/Makefile +++ b/t/Makefile @@ -28,4 +28,3 @@ full-svn-test: .PHONY: $(T) clean .NOTPARALLEL: - diff --git a/t/lib-read-tree-m-3way.sh b/t/lib-read-tree-m-3way.sh index d195603dfa..586df2113f 100644 --- a/t/lib-read-tree-m-3way.sh +++ b/t/lib-read-tree-m-3way.sh @@ -87,7 +87,7 @@ test_expect_success \ test_expect_success \ 'recording branch A tree' \ 'tree_A=$(git-write-tree)' - + ################################################################ # Branch B # Start from O diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 186de70243..8bfe8320ea 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -37,7 +37,7 @@ fi find .git/objects -type f -print >should-be-empty test_expect_success \ '.git/objects should be empty after git-init in an empty repo.' \ - 'cmp -s /dev/null should-be-empty' + 'cmp -s /dev/null should-be-empty' # also it should have 2 subdirectories; no fan-out anymore, pack, and info. # 3 is counting "objects" itself diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh index ca2c30f7af..d3f8358485 100755 --- a/t/t1200-tutorial.sh +++ b/t/t1200-tutorial.sh @@ -159,4 +159,3 @@ test_expect_success 'git prune-packed' 'git prune-packed' test_expect_failure '-> only packed objects' 'find -type f .git/objects/[0-9a-f][0-9a-f]' test_done - diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index 3f3fd2d7f7..7731fa72ce 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -514,4 +514,3 @@ git config --list > result test_expect_success 'value continued on next line' 'cmp result expect' test_done - diff --git a/t/t2000-checkout-cache-clash.sh b/t/t2000-checkout-cache-clash.sh index 03ea4dece4..d556b41f13 100755 --- a/t/t2000-checkout-cache-clash.sh +++ b/t/t2000-checkout-cache-clash.sh @@ -49,5 +49,3 @@ test_expect_success \ 'test -f path0 && test -d path1 && test -f path1/file1' test_done - - diff --git a/t/t2001-checkout-cache-clash.sh b/t/t2001-checkout-cache-clash.sh index 0dcab8f1de..b895a0fe36 100755 --- a/t/t2001-checkout-cache-clash.sh +++ b/t/t2001-checkout-cache-clash.sh @@ -84,4 +84,3 @@ test_expect_success \ test ! -h path1/file1 && test -f path1/file1' test_done - diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index 86ee2b0bd3..607f57ff94 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -525,4 +525,3 @@ test_expect_success 'reset and bind merge' ' ' test_done - diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh index 977c498f00..9e11ed295d 100755 --- a/t/t3403-rebase-skip.sh +++ b/t/t3403-rebase-skip.sh @@ -54,4 +54,3 @@ test_expect_success 'merge and reference trees equal' \ test_debug 'gitk --all & sleep 1' test_done - diff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh index e72c6fd1b4..b8acca1813 100755 --- a/t/t4006-diff-mode.sh +++ b/t/t4006-diff-mode.sh @@ -41,4 +41,3 @@ test_expect_success \ 'git diff expected check' test_done - diff --git a/t/t4100-apply-stat.sh b/t/t4100-apply-stat.sh index 7b81c32e57..c23341feb5 100755 --- a/t/t4100-apply-stat.sh +++ b/t/t4100-apply-stat.sh @@ -44,4 +44,3 @@ test_expect_success \ git diff ../t4100/t-apply-7.expect current' test_done - diff --git a/t/t4110-apply-scan.sh b/t/t4110-apply-scan.sh index 005f744816..9faef0d66e 100755 --- a/t/t4110-apply-scan.sh +++ b/t/t4110-apply-scan.sh @@ -98,4 +98,3 @@ test_expect_success "S = cmp" \ 'cmp apply.txt patch.txt' test_done - diff --git a/t/t4112-apply-renames.sh b/t/t4112-apply-renames.sh index 69e9603c78..9baf810bee 100755 --- a/t/t4112-apply-renames.sh +++ b/t/t4112-apply-renames.sh @@ -49,10 +49,10 @@ copy to include/arch/cris/klibc/archsetjmp.h - * arch/x86_64/include/klibc/archsetjmp.h + * arch/cris/include/klibc/archsetjmp.h */ - + #ifndef _KLIBC_ARCHSETJMP_H #define _KLIBC_ARCHSETJMP_H - + struct __jmp_buf { - unsigned long __rbx; - unsigned long __rsp; @@ -74,9 +74,9 @@ copy to include/arch/cris/klibc/archsetjmp.h + unsigned long __sp; + unsigned long __srp; }; - + typedef struct __jmp_buf jmp_buf[1]; - + -#endif /* _SETJMP_H */ +#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/arch/x86_64/include/klibc/archsetjmp.h b/include/arch/m32r/klibc/archsetjmp.h @@ -90,10 +90,10 @@ rename to include/arch/m32r/klibc/archsetjmp.h - * arch/x86_64/include/klibc/archsetjmp.h + * arch/m32r/include/klibc/archsetjmp.h */ - + #ifndef _KLIBC_ARCHSETJMP_H #define _KLIBC_ARCHSETJMP_H - + struct __jmp_buf { - unsigned long __rbx; - unsigned long __rsp; @@ -108,9 +108,9 @@ rename to include/arch/m32r/klibc/archsetjmp.h unsigned long __r15; - unsigned long __rip; }; - + typedef struct __jmp_buf jmp_buf[1]; - + -#endif /* _SETJMP_H */ +#endif /* _KLIBC_ARCHSETJMP_H */ EOF diff --git a/t/t4118-apply-empty-context.sh b/t/t4118-apply-empty-context.sh index 27cc6f2b88..dd88e81e04 100755 --- a/t/t4118-apply-empty-context.sh +++ b/t/t4118-apply-empty-context.sh @@ -53,4 +53,3 @@ test_expect_success 'apply --apply' ' ' test_done - diff --git a/t/t4119-apply-config.sh b/t/t4119-apply-config.sh index 620a9207bf..edae7056e4 100755 --- a/t/t4119-apply-config.sh +++ b/t/t4119-apply-config.sh @@ -24,7 +24,7 @@ cat >gpatch.file <<\EOF && +++ file1+ 2007-02-21 01:07:44.000000000 -0800 @@ -1 +1 @@ -A -+B ++B EOF sed -e 's|file1|sub/&|' gpatch.file >gpatch-sub.file && diff --git a/t/t4121-apply-diffs.sh b/t/t4121-apply-diffs.sh index 2b2f1eda21..b95b89c341 100755 --- a/t/t4121-apply-diffs.sh +++ b/t/t4121-apply-diffs.sh @@ -30,4 +30,3 @@ test_expect_success \ '( git diff test~2 test~1; git diff test~1 test~0 )| git apply' test_done - diff --git a/t/t4122-apply-symlink-inside.sh b/t/t4122-apply-symlink-inside.sh index 3ddfe64b02..841773f75f 100755 --- a/t/t4122-apply-symlink-inside.sh +++ b/t/t4122-apply-symlink-inside.sh @@ -53,4 +53,3 @@ test_expect_success 'check result' ' ' test_done - diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index c64ebbb2e9..a46d7f74be 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -148,5 +148,3 @@ test_expect_success 'old records rest in peace' \ "test ! -f $rr/preimage && test ! -f $rr2/preimage" test_done - - diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh index 477b267599..4eaea8f336 100755 --- a/t/t5400-send-pack.sh +++ b/t/t5400-send-pack.sh @@ -66,7 +66,7 @@ test_expect_success 'pack the destination repository' ' ' test_expect_success \ - 'pushing rewound head should not barf but require --force' ' + 'pushing rewound head should not barf but require --force' ' # should not fail but refuse to update. if git-send-pack ./victim/.git/ master then diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 243212d3da..93eaf2c154 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -54,4 +54,3 @@ test_expect_success 'the default remote . should not break explicit pull' ' ' test_done - diff --git a/t/t5710-info-alternate.sh b/t/t5710-info-alternate.sh index 2f8e97cb7e..699df6ebd8 100755 --- a/t/t5710-info-alternate.sh +++ b/t/t5710-info-alternate.sh @@ -104,4 +104,3 @@ test_valid_repo' cd "$base_dir" test_done - diff --git a/t/t6000lib.sh b/t/t6000lib.sh index d40262159b..d548bf8026 100755 --- a/t/t6000lib.sh +++ b/t/t6000lib.sh @@ -17,17 +17,17 @@ unique_commit() _text=$1 _tree=$2 shift 2 - echo $_text | git-commit-tree $(tag $_tree) "$@" + echo $_text | git-commit-tree $(tag $_tree) "$@" } # Save the output of a command into the tag specified. Prepend # a substitution script for the tag onto the front of sed.script save_tag() { - _tag=$1 + _tag=$1 [ -n "$_tag" ] || error "usage: save_tag tag commit-args ..." shift 1 - "$@" >.git/refs/tags/$_tag + "$@" >.git/refs/tags/$_tag echo "s/$(tag $_tag)/$_tag/g" > sed.script.tmp cat sed.script >> sed.script.tmp @@ -35,7 +35,7 @@ save_tag() mv sed.script.tmp sed.script } -# Replace unhelpful sha1 hashses with their symbolic equivalents +# Replace unhelpful sha1 hashses with their symbolic equivalents entag() { sed -f sed.script @@ -62,7 +62,7 @@ as_author() commit_date() { _commit=$1 - git-cat-file commit $_commit | sed -n "s/^committer .*> \([0-9]*\) .*/\1/p" + git-cat-file commit $_commit | sed -n "s/^committer .*> \([0-9]*\) .*/\1/p" } on_committer_date() @@ -103,14 +103,14 @@ name_from_description() # Execute the test described by the first argument, by eval'ing # command line specified in the 2nd argument. Check the status code -# is zero and that the output matches the stream read from +# is zero and that the output matches the stream read from # stdin. test_output_expect_success() -{ +{ _description=$1 _test=$2 [ $# -eq 2 ] || error "usage: test_output_expect_success description test < $_name.expected - test_expect_success "$_description" "check_output $_name \"$_test\"" + test_expect_success "$_description" "check_output $_name \"$_test\"" } diff --git a/t/t6002-rev-list-bisect.sh b/t/t6002-rev-list-bisect.sh index fcb3302764..71cbb72e1b 100755 --- a/t/t6002-rev-list-bisect.sh +++ b/t/t6002-rev-list-bisect.sh @@ -26,7 +26,7 @@ test_bisection_diff() # Test if bisection size is close to half of list size within # tolerance. - # + # _bisect_err=`expr $_list_size - $_bisection_size \* 2` test "$_bisect_err" -lt 0 && _bisect_err=`expr 0 - $_bisect_err` _bisect_err=`expr $_bisect_err / 2` ; # floor @@ -116,8 +116,8 @@ on_committer_date "1971-08-16 00:00:06" save_tag V unique_commit V tree -p u1 -p test_sequence() { - _bisect_option=$1 - + _bisect_option=$1 + test_bisection_diff 0 $_bisect_option l0 ^root test_bisection_diff 0 $_bisect_option l1 ^root test_bisection_diff 0 $_bisect_option l2 ^root @@ -152,7 +152,7 @@ test_sequence() test_bisection_diff 0 $_bisect_option u3 ^U test_bisection_diff 0 $_bisect_option u4 ^U test_bisection_diff 0 $_bisect_option u5 ^U - + # # the following illustrates Linus' binary bug blatt idea. # diff --git a/t/t6021-merge-criss-cross.sh b/t/t6021-merge-criss-cross.sh index 499cafb882..0ab14a6e81 100755 --- a/t/t6021-merge-criss-cross.sh +++ b/t/t6021-merge-criss-cross.sh @@ -20,7 +20,7 @@ test_expect_success 'prepare repository' \ 7 8 9" > file && -git add file && +git add file && git commit -m "Initial commit" file && git branch A && git branch B && diff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh index c76fccfb5a..43aa5d033d 100755 --- a/t/t6023-merge-file.sh +++ b/t/t6023-merge-file.sh @@ -135,4 +135,3 @@ EOF test_expect_success "expected conflict markers" "git diff expect out" test_done - diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index 30f6ade13f..03cdba5808 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -102,4 +102,3 @@ test_expect_success \ # # test_done - diff --git a/t/t6101-rev-parse-parents.sh b/t/t6101-rev-parse-parents.sh index b0252b9413..dd6cc3a55c 100755 --- a/t/t6101-rev-parse-parents.sh +++ b/t/t6101-rev-parse-parents.sh @@ -40,4 +40,3 @@ test_expect_success 'short SHA-1 works' ' test $start = $abbrv' test_done - diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh index dc2afdaa45..d549665400 100755 --- a/t/t9107-git-svn-migrate.sh +++ b/t/t9107-git-svn-migrate.sh @@ -109,4 +109,3 @@ test_expect_success ".rev_db auto-converted to .rev_db.UUID" " " test_done - diff --git a/t/t9111/svnsync.dump b/t/t9111/svnsync.dump index a9a46eeb29..499fa9594f 100644 --- a/t/t9111/svnsync.dump +++ b/t/t9111/svnsync.dump @@ -558,5 +558,3 @@ Text-content-md5: 7abb78de7f2756ca8b511cbc879fd5e7 Content-length: 4 cba - - diff --git a/t/test-lib.sh b/t/test-lib.sh index dee3ad7621..8bf4cf49a2 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -232,7 +232,7 @@ test_create_repo () { mv .git/hooks .git/hooks-disabled cd "$owd" } - + test_done () { trap - exit case "$test_failure" in diff --git a/templates/hooks--commit-msg b/templates/hooks--commit-msg index 9b04f2d69c..c5cdb9d7ee 100644 --- a/templates/hooks--commit-msg +++ b/templates/hooks--commit-msg @@ -19,4 +19,3 @@ test "" = "$(grep '^Signed-off-by: ' "$1" | echo >&2 Duplicate Signed-off-by lines. exit 1 } - diff --git a/templates/hooks--post-receive b/templates/hooks--post-receive index 190de2688c..b70c8fd364 100644 --- a/templates/hooks--post-receive +++ b/templates/hooks--post-receive @@ -14,4 +14,3 @@ #. /usr/share/doc/git-core/contrib/hooks/post-receive-email - diff --git a/templates/hooks--pre-applypatch b/templates/hooks--pre-applypatch index 5f56ce8053..eeccc934ca 100644 --- a/templates/hooks--pre-applypatch +++ b/templates/hooks--pre-applypatch @@ -12,4 +12,3 @@ test -x "$GIT_DIR/hooks/pre-commit" && exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} : - diff --git a/templates/hooks--pre-commit b/templates/hooks--pre-commit index 723a9ef210..18b87309f6 100644 --- a/templates/hooks--pre-commit +++ b/templates/hooks--pre-commit @@ -68,4 +68,3 @@ perl -e ' } exit($found_bad); ' - diff --git a/tree-walk.c b/tree-walk.c index cbb24eb3f6..8d4b67317f 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -206,4 +206,3 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch free(tree); return retval; } - diff --git a/upload-pack.c b/upload-pack.c index d3a09e78d5..0e881c85b5 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -678,7 +678,7 @@ int main(int argc, char **argv) break; } } - + if (i != argc-1) usage(upload_pack_usage); dir = argv[i]; diff --git a/var.c b/var.c index e585e59d31..4127031910 100644 --- a/var.c +++ b/var.c @@ -67,8 +67,8 @@ int main(int argc, char **argv) val = read_var(argv[1]); if (!val) usage(var_usage); - + printf("%s\n", val); - + return 0; } diff --git a/xdiff-interface.c b/xdiff-interface.c index 963bb89b08..e407cf11b1 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -129,5 +129,3 @@ int buffer_is_binary(const char *ptr, unsigned long size) size = FIRST_FEW_BYTES; return !!memchr(ptr, 0, size); } - - diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h index e874a7c46a..9402bb0799 100644 --- a/xdiff/xdiff.h +++ b/xdiff/xdiff.h @@ -103,4 +103,3 @@ int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1, #endif /* #ifdef __cplusplus */ #endif /* #if !defined(XDIFF_H) */ - diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c index 9aeebc473b..5cb7171a8f 100644 --- a/xdiff/xdiffi.c +++ b/xdiff/xdiffi.c @@ -565,4 +565,3 @@ int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, return 0; } - diff --git a/xdiff/xdiffi.h b/xdiff/xdiffi.h index 472aeaecfa..3e099dc445 100644 --- a/xdiff/xdiffi.h +++ b/xdiff/xdiffi.h @@ -57,4 +57,3 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, xdemitconf_t const *xecfg); #endif /* #if !defined(XDIFFI_H) */ - diff --git a/xdiff/xemit.c b/xdiff/xemit.c index e291dc7608..78b1d4b8bb 100644 --- a/xdiff/xemit.c +++ b/xdiff/xemit.c @@ -194,4 +194,3 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, return 0; } - diff --git a/xdiff/xemit.h b/xdiff/xemit.h index e629417dd2..440a7390fa 100644 --- a/xdiff/xemit.h +++ b/xdiff/xemit.h @@ -31,4 +31,3 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, #endif /* #if !defined(XEMIT_H) */ - diff --git a/xdiff/xinclude.h b/xdiff/xinclude.h index 04a9da82c9..526ccb344d 100644 --- a/xdiff/xinclude.h +++ b/xdiff/xinclude.h @@ -40,4 +40,3 @@ #endif /* #if !defined(XINCLUDE_H) */ - diff --git a/xdiff/xmacros.h b/xdiff/xmacros.h index e2cd2023b3..8ef232cfad 100644 --- a/xdiff/xmacros.h +++ b/xdiff/xmacros.h @@ -51,4 +51,3 @@ do { \ #endif /* #if !defined(XMACROS_H) */ - diff --git a/xdiff/xprepare.c b/xdiff/xprepare.c index 1be7b31950..e87ab57c65 100644 --- a/xdiff/xprepare.c +++ b/xdiff/xprepare.c @@ -466,4 +466,3 @@ static int xdl_optimize_ctxs(xdfile_t *xdf1, xdfile_t *xdf2) { return 0; } - diff --git a/xdiff/xprepare.h b/xdiff/xprepare.h index 344c569e8b..8fb06a5374 100644 --- a/xdiff/xprepare.h +++ b/xdiff/xprepare.h @@ -32,4 +32,3 @@ void xdl_free_env(xdfenv_t *xe); #endif /* #if !defined(XPREPARE_H) */ - diff --git a/xdiff/xtypes.h b/xdiff/xtypes.h index 3593a664fc..2511aef8d8 100644 --- a/xdiff/xtypes.h +++ b/xdiff/xtypes.h @@ -65,4 +65,3 @@ typedef struct s_xdfenv { #endif /* #if !defined(XTYPES_H) */ - diff --git a/xdiff/xutils.c b/xdiff/xutils.c index bf91c0f73c..2ade97b257 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -380,4 +380,3 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, return 0; } - diff --git a/xdiff/xutils.h b/xdiff/xutils.h index 70d8b9838a..d5de8292e0 100644 --- a/xdiff/xutils.h +++ b/xdiff/xutils.h @@ -45,4 +45,3 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, #endif /* #if !defined(XUTILS_H) */ - -- cgit v1.3 From 4d3f4b80e49275c7eaf6ba0dbddd6180957926b9 Mon Sep 17 00:00:00 2001 From: René Scharfe Date: Sat, 7 Jul 2007 20:19:08 +0200 Subject: diff-lib.c: don't strdup twice The static function read_directory in diff-lib.c is only ever called with struct path_list lists with .strdup_paths turned on, i.e. path_list_insert will strdup the paths for us (again). Let's take advantage of that and stop doing it twice. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- diff-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index 7fb19c7b87..92c0e39ad6 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -24,7 +24,7 @@ static int read_directory(const char *path, struct path_list *list) while ((e = readdir(dir))) if (strcmp(".", e->d_name) && strcmp("..", e->d_name)) - path_list_insert(xstrdup(e->d_name), list); + path_list_insert(e->d_name, list); closedir(dir); return 0; -- cgit v1.3 From 6d2d9e8666ef72c8878af4822e243ca33b6752a0 Mon Sep 17 00:00:00 2001 From: René Scharfe Date: Wed, 15 Aug 2007 00:41:00 +0200 Subject: diff: squelch empty diffs even more When we compare two non-tracked files, or explicitly specify --no-index, the suggestion to run git-status is not helpful. The patch adds a new diff_options bitfield member, no_index, that is used instead of the special value of -2 of the rev_info field max_count to indicate that the index is not to be used. This makes it possible to pass that flag down to diffcore_skip_stat_unmatch(), which only has one diff_options parameter. This could even become a cleanup if we removed all assignments of max_count to a value of -2 (viz. replacement of a magic value with a self-documenting field name) but I didn't dare to do that so late in the rc game.. The no_index bit, if set, then tells diffcore_skip_stat_unmatch() to not account for any skipped stat-mismatches, which avoids the suggestion to run git-status. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- diff-lib.c | 8 ++++++-- diff.c | 3 ++- diff.h | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index 92c0e39ad6..f5568c3b36 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -189,6 +189,7 @@ static int handle_diff_files_args(struct rev_info *revs, !strcmp(argv[1], "--no-index")) { revs->max_count = -2; revs->diffopt.exit_with_status = 1; + revs->diffopt.no_index = 1; } else if (!strcmp(argv[1], "-q")) *silent = 1; @@ -204,8 +205,10 @@ static int handle_diff_files_args(struct rev_info *revs, */ read_cache(); if (!is_in_index(revs->diffopt.paths[0]) || - !is_in_index(revs->diffopt.paths[1])) + !is_in_index(revs->diffopt.paths[1])) { revs->max_count = -2; + revs->diffopt.no_index = 1; + } } /* @@ -293,6 +296,7 @@ int setup_diff_no_index(struct rev_info *revs, else revs->diffopt.paths = argv + argc - 2; revs->diffopt.nr_paths = 2; + revs->diffopt.no_index = 1; revs->max_count = -2; return 0; } @@ -304,7 +308,7 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) if (handle_diff_files_args(revs, argc, argv, &silent_on_removed)) return -1; - if (revs->max_count == -2) { + if (revs->diffopt.no_index) { if (revs->diffopt.nr_paths != 2) return error("need two files/directories with --no-index"); if (queue_diff(&revs->diffopt, revs->diffopt.paths[0], diff --git a/diff.c b/diff.c index f884de77ac..97cc5bc085 100644 --- a/diff.c +++ b/diff.c @@ -3185,7 +3185,8 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt) * to determine how many paths were dirty only * due to stat info mismatch. */ - diffopt->skip_stat_unmatch++; + if (!diffopt->no_index) + diffopt->skip_stat_unmatch++; diff_free_filepair(p); } } diff --git a/diff.h b/diff.h index de21f8ecd0..4546aad219 100644 --- a/diff.h +++ b/diff.h @@ -60,6 +60,7 @@ struct diff_options { color_diff_words:1, has_changes:1, quiet:1, + no_index:1, allow_external:1, exit_with_status:1; int context; -- cgit v1.3 From b78281f7215c0236da6bd5c04ec5e500c83fd101 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 14 Sep 2007 12:12:32 -0700 Subject: diff --no-index: do not forget to run diff_setup_done() Code inspection by Linus found this. Signed-off-by: Junio C Hamano --- diff-lib.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index f5568c3b36..da5571302d 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -298,6 +298,8 @@ int setup_diff_no_index(struct rev_info *revs, revs->diffopt.nr_paths = 2; revs->diffopt.no_index = 1; revs->max_count = -2; + if (diff_setup_done(&revs->diffopt) < 0) + die("diff_setup_done failed"); return 0; } -- cgit v1.3 From 4bd5b7dacc404e6b733d9ab6744429c5027bb5e1 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 10 Nov 2007 00:15:03 -0800 Subject: ce_match_stat, run_diff_files: use symbolic constants for readability ce_match_stat() can be told: (1) to ignore CE_VALID bit (used under "assume unchanged" mode) and perform the stat comparison anyway; (2) not to perform the contents comparison for racily clean entries and report mismatch of cached stat information; using its "option" parameter. Give them symbolic constants. Similarly, run_diff_files() can be told not to report anything on removed paths. Also give it a symbolic constant for that. Signed-off-by: Junio C Hamano --- builtin-apply.c | 2 +- cache.h | 14 ++++++++++---- check-racy.c | 2 +- diff-lib.c | 16 +++++++++------- diff.h | 4 +++- entry.c | 2 +- read-cache.c | 47 ++++++++++++++++++++++++++++++----------------- unpack-trees.c | 4 ++-- 8 files changed, 57 insertions(+), 34 deletions(-) (limited to 'diff-lib.c') diff --git a/builtin-apply.c b/builtin-apply.c index 5cc90e68f8..0fff02e0d8 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -2099,7 +2099,7 @@ static int verify_index_match(struct cache_entry *ce, struct stat *st) return -1; return 0; } - return ce_match_stat(ce, st, 1); + return ce_match_stat(ce, st, CE_MATCH_IGNORE_VALID); } static int check_patch(struct patch *patch, struct patch *prev_patch) diff --git a/cache.h b/cache.h index fc195bc47c..31af16a7ee 100644 --- a/cache.h +++ b/cache.h @@ -174,8 +174,8 @@ extern struct index_state the_index; #define remove_file_from_cache(path) remove_file_from_index(&the_index, (path)) #define add_file_to_cache(path, verbose) add_file_to_index(&the_index, (path), (verbose)) #define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL) -#define ce_match_stat(ce, st, really) ie_match_stat(&the_index, (ce), (st), (really)) -#define ce_modified(ce, st, really) ie_modified(&the_index, (ce), (st), (really)) +#define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options)) +#define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options)) #endif enum object_type { @@ -266,8 +266,14 @@ extern int remove_file_from_index(struct index_state *, const char *path); extern int add_file_to_index(struct index_state *, const char *path, int verbose); extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh); extern int ce_same_name(struct cache_entry *a, struct cache_entry *b); -extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat *, int); -extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, int); + +/* do stat comparison even if CE_VALID is true */ +#define CE_MATCH_IGNORE_VALID 01 +/* do not check the contents but report dirty on racily-clean entries */ +#define CE_MATCH_RACY_IS_DIRTY 02 +extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat *, unsigned int); +extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, unsigned int); + extern int ce_path_match(const struct cache_entry *ce, const char **pathspec); extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path); extern int read_fd(int fd, char **return_buf, unsigned long *return_size); diff --git a/check-racy.c b/check-racy.c index d6a08b4a55..00d92a1663 100644 --- a/check-racy.c +++ b/check-racy.c @@ -18,7 +18,7 @@ int main(int ac, char **av) if (ce_match_stat(ce, &st, 0)) dirty++; - else if (ce_match_stat(ce, &st, 2)) + else if (ce_match_stat(ce, &st, CE_MATCH_RACY_IS_DIRTY)) racy++; else clean++; diff --git a/diff-lib.c b/diff-lib.c index da5571302d..9f8afbe71a 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -173,9 +173,10 @@ static int is_in_index(const char *path) } static int handle_diff_files_args(struct rev_info *revs, - int argc, const char **argv, int *silent) + int argc, const char **argv, + unsigned int *options) { - *silent = 0; + *options = 0; /* revs->max_count == -2 means --no-index */ while (1 < argc && argv[1][0] == '-') { @@ -192,7 +193,7 @@ static int handle_diff_files_args(struct rev_info *revs, revs->diffopt.no_index = 1; } else if (!strcmp(argv[1], "-q")) - *silent = 1; + *options |= DIFF_SILENT_ON_REMOVED; else return error("invalid option: %s", argv[1]); argv++; argc--; @@ -305,9 +306,9 @@ int setup_diff_no_index(struct rev_info *revs, int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) { - int silent_on_removed; + unsigned int options; - if (handle_diff_files_args(revs, argc, argv, &silent_on_removed)) + if (handle_diff_files_args(revs, argc, argv, &options)) return -1; if (revs->diffopt.no_index) { @@ -329,13 +330,14 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) perror("read_cache"); return -1; } - return run_diff_files(revs, silent_on_removed); + return run_diff_files(revs, options); } -int run_diff_files(struct rev_info *revs, int silent_on_removed) +int run_diff_files(struct rev_info *revs, unsigned int option) { int entries, i; int diff_unmerged_stage = revs->max_count; + int silent_on_removed = option & DIFF_SILENT_ON_REMOVED; if (diff_unmerged_stage < 0) diff_unmerged_stage = 2; diff --git a/diff.h b/diff.h index 4546aad219..de533da15d 100644 --- a/diff.h +++ b/diff.h @@ -224,7 +224,9 @@ extern void diff_flush(struct diff_options*); extern const char *diff_unique_abbrev(const unsigned char *, int); -extern int run_diff_files(struct rev_info *revs, int silent_on_removed); +/* do not report anything on removed paths */ +#define DIFF_SILENT_ON_REMOVED 01 +extern int run_diff_files(struct rev_info *revs, unsigned int option); extern int setup_diff_no_index(struct rev_info *revs, int argc, const char ** argv, int nongit, const char *prefix); extern int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv); diff --git a/entry.c b/entry.c index fc3a506ece..ef88f62ce8 100644 --- a/entry.c +++ b/entry.c @@ -200,7 +200,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t strcpy(path + len, ce->name); if (!lstat(path, &st)) { - unsigned changed = ce_match_stat(ce, &st, 1); + unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID); if (!changed) return 0; if (!state->force) { diff --git a/read-cache.c b/read-cache.c index 928e8fa1ae..9e4d4a9136 100644 --- a/read-cache.c +++ b/read-cache.c @@ -194,11 +194,12 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st) } int ie_match_stat(struct index_state *istate, - struct cache_entry *ce, struct stat *st, int options) + struct cache_entry *ce, struct stat *st, + unsigned int options) { unsigned int changed; - int ignore_valid = options & 01; - int assume_racy_is_modified = options & 02; + int ignore_valid = options & CE_MATCH_IGNORE_VALID; + int assume_racy_is_modified = options & CE_MATCH_RACY_IS_DIRTY; /* * If it's marked as always valid in the index, it's @@ -238,10 +239,11 @@ int ie_match_stat(struct index_state *istate, } int ie_modified(struct index_state *istate, - struct cache_entry *ce, struct stat *st, int really) + struct cache_entry *ce, struct stat *st, unsigned int options) { int changed, changed_fs; - changed = ie_match_stat(istate, ce, st, really); + + changed = ie_match_stat(istate, ce, st, options); if (!changed) return 0; /* @@ -420,7 +422,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose) pos = index_name_pos(istate, ce->name, namelen); if (0 <= pos && !ce_stage(istate->cache[pos]) && - !ie_modified(istate, istate->cache[pos], &st, 1)) { + !ie_modified(istate, istate->cache[pos], &st, CE_MATCH_IGNORE_VALID)) { /* Nothing changed, really */ free(ce); return 0; @@ -782,11 +784,13 @@ int add_index_entry(struct index_state *istate, struct cache_entry *ce, int opti * to link up the stat cache details with the proper files. */ static struct cache_entry *refresh_cache_ent(struct index_state *istate, - struct cache_entry *ce, int really, int *err) + struct cache_entry *ce, + unsigned int options, int *err) { struct stat st; struct cache_entry *updated; int changed, size; + int ignore_valid = options & CE_MATCH_IGNORE_VALID; if (lstat(ce->name, &st) < 0) { if (err) @@ -794,16 +798,23 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate, return NULL; } - changed = ie_match_stat(istate, ce, &st, really); + changed = ie_match_stat(istate, ce, &st, options); if (!changed) { - if (really && assume_unchanged && + /* + * The path is unchanged. If we were told to ignore + * valid bit, then we did the actual stat check and + * found that the entry is unmodified. If the entry + * is not marked VALID, this is the place to mark it + * valid again, under "assume unchanged" mode. + */ + if (ignore_valid && assume_unchanged && !(ce->ce_flags & htons(CE_VALID))) ; /* mark this one VALID again */ else return ce; } - if (ie_modified(istate, ce, &st, really)) { + if (ie_modified(istate, ce, &st, options)) { if (err) *err = EINVAL; return NULL; @@ -814,13 +825,14 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate, memcpy(updated, ce, size); fill_stat_cache_info(updated, &st); - /* In this case, if really is not set, we should leave - * CE_VALID bit alone. Otherwise, paths marked with - * --no-assume-unchanged (i.e. things to be edited) will - * reacquire CE_VALID bit automatically, which is not - * really what we want. + /* + * If ignore_valid is not set, we should leave CE_VALID bit + * alone. Otherwise, paths marked with --no-assume-unchanged + * (i.e. things to be edited) will reacquire CE_VALID bit + * automatically, which is not really what we want. */ - if (!really && assume_unchanged && !(ce->ce_flags & htons(CE_VALID))) + if (!ignore_valid && assume_unchanged && + !(ce->ce_flags & htons(CE_VALID))) updated->ce_flags &= ~htons(CE_VALID); return updated; @@ -834,6 +846,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p int allow_unmerged = (flags & REFRESH_UNMERGED) != 0; int quiet = (flags & REFRESH_QUIET) != 0; int not_new = (flags & REFRESH_IGNORE_MISSING) != 0; + unsigned int options = really ? CE_MATCH_IGNORE_VALID : 0; for (i = 0; i < istate->cache_nr; i++) { struct cache_entry *ce, *new; @@ -855,7 +868,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p if (pathspec && !match_pathspec(pathspec, ce->name, strlen(ce->name), 0, seen)) continue; - new = refresh_cache_ent(istate, ce, really, &cache_errno); + new = refresh_cache_ent(istate, ce, options, &cache_errno); if (new == ce) continue; if (!new) { diff --git a/unpack-trees.c b/unpack-trees.c index ccfeb6e245..9411c67a06 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -406,7 +406,7 @@ static void verify_uptodate(struct cache_entry *ce, return; if (!lstat(ce->name, &st)) { - unsigned changed = ce_match_stat(ce, &st, 1); + unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID); if (!changed) return; /* @@ -927,7 +927,7 @@ int oneway_merge(struct cache_entry **src, if (o->reset) { struct stat st; if (lstat(old->name, &st) || - ce_match_stat(old, &st, 1)) + ce_match_stat(old, &st, CE_MATCH_IGNORE_VALID)) old->ce_flags |= htons(CE_UPDATE); } return keep_entry(old, o); -- cgit v1.3 From fb63d7f889cf5df417b731b07952689df7f745c8 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 9 Nov 2007 18:22:52 -0800 Subject: git-add: make the entry stat-clean after re-adding the same contents Earlier in commit 0781b8a9b2fe760fc4ed519a3a26e4b9bd6ccffe (add_file_to_index: skip rehashing if the cached stat already matches), add_file_to_index() were taught not to re-add the path if it already matches the index. The change meant well, but was not executed quite right. It used ie_modified() to see if the file on the work tree is really different from the index, and skipped adding the contents if the function says "not modified". This was wrong. There are three possible comparison results between the index and the file in the work tree: - with lstat(2) we _know_ they are different. E.g. if the length or the owner in the cached stat information is different from the length we just obtained from lstat(2), we can tell the file is modified without looking at the actual contents. - with lstat(2) we _know_ they are the same. The same length, the same owner, the same everything (but this has a twist, as described below). - we cannot tell from lstat(2) information alone and need to go to the filesystem to actually compare. The last case arises from what we call 'racy git' situation, that can be caused with this sequence: $ echo hello >file $ git add file $ echo aeiou >file ;# the same length If the second "echo" is done within the same filesystem timestamp granularity as the first "echo", then the timestamp recorded by "git add" and the timestamp we get from lstat(2) will be the same, and we can mistakenly say the file is not modified. The path is called 'racily clean'. We need to reliably detect racily clean paths are in fact modified. To solve this problem, when we write out the index, we mark the index entry that has the same timestamp as the index file itself (that is the time from the point of view of the filesystem) to tell any later code that does the lstat(2) comparison not to trust the cached stat info, and ie_modified() then actually goes to the filesystem to compare the contents for such a path. That's all good, but it should not be used for this "git add" optimization, as the goal of "git add" is to actually update the path in the index and make it stat-clean. With the false optimization, we did _not_ cause any data loss (after all, what we failed to do was only to update the cached stat information), but it made the following sequence leave the file stat dirty: $ echo hello >file $ git add file $ echo hello >file ;# the same contents $ git add file The solution is not to use ie_modified() which goes to the filesystem to see if it is really clean, but instead use ie_match_stat() with "assume racily clean paths are dirty" option, to force re-adding of such a path. There was another problem with "git add -u". The codepath shares the same issue when adding the paths that are found to be modified, but in addition, it asked "git diff-files" machinery run_diff_files() function (which is "git diff-files") to list the paths that are modified. But "git diff-files" machinery uses the same ie_modified() call so that it does not report racily clean _and_ actually clean paths as modified, which is not what we want. The patch allows the callers of run_diff_files() to pass the same "assume racily clean paths are dirty" option, and makes "git-add -u" codepath to use that option, to discover and re-add racily clean _and_ actually clean paths. We could further optimize on top of this patch to differentiate the case where the path really needs re-adding (i.e. the content of the racily clean entry was indeed different) and the case where only the cached stat information needs to be refreshed (i.e. the racily clean entry was actually clean), but I do not think it is worth it. This patch applies to maint and all the way up. Signed-off-by: Junio C Hamano --- builtin-add.c | 2 +- diff-lib.c | 4 +++- diff.h | 2 ++ read-cache.c | 3 ++- 4 files changed, 8 insertions(+), 3 deletions(-) (limited to 'diff-lib.c') diff --git a/builtin-add.c b/builtin-add.c index 373f87f9f2..e072320d20 100644 --- a/builtin-add.c +++ b/builtin-add.c @@ -123,7 +123,7 @@ static void update(int verbose, const char *prefix, const char **files) rev.diffopt.format_callback_data = &verbose; if (read_cache() < 0) die("index file corrupt"); - run_diff_files(&rev, 0); + run_diff_files(&rev, DIFF_RACY_IS_MODIFIED); } static void refresh(int verbose, const char **pathspec) diff --git a/diff-lib.c b/diff-lib.c index 9f8afbe71a..ec1b5e3d44 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -338,6 +338,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option) int entries, i; int diff_unmerged_stage = revs->max_count; int silent_on_removed = option & DIFF_SILENT_ON_REMOVED; + unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED) + ? CE_MATCH_RACY_IS_DIRTY : 0); if (diff_unmerged_stage < 0) diff_unmerged_stage = 2; @@ -443,7 +445,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) ce->sha1, ce->name, NULL); continue; } - changed = ce_match_stat(ce, &st, 0); + changed = ce_match_stat(ce, &st, ce_option); if (!changed && !revs->diffopt.find_copies_harder) continue; oldmode = ntohl(ce->ce_mode); diff --git a/diff.h b/diff.h index de533da15d..efaa8f711a 100644 --- a/diff.h +++ b/diff.h @@ -226,6 +226,8 @@ extern const char *diff_unique_abbrev(const unsigned char *, int); /* do not report anything on removed paths */ #define DIFF_SILENT_ON_REMOVED 01 +/* report racily-clean paths as modified */ +#define DIFF_RACY_IS_MODIFIED 02 extern int run_diff_files(struct rev_info *revs, unsigned int option); extern int setup_diff_no_index(struct rev_info *revs, int argc, const char ** argv, int nongit, const char *prefix); diff --git a/read-cache.c b/read-cache.c index 9e4d4a9136..c3dbf89426 100644 --- a/read-cache.c +++ b/read-cache.c @@ -388,6 +388,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose) int size, namelen, pos; struct stat st; struct cache_entry *ce; + unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_RACY_IS_DIRTY; if (lstat(path, &st)) die("%s: unable to stat (%s)", path, strerror(errno)); @@ -422,7 +423,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose) pos = index_name_pos(istate, ce->name, namelen); if (0 <= pos && !ce_stage(istate->cache[pos]) && - !ie_modified(istate, istate->cache[pos], &st, CE_MATCH_IGNORE_VALID)) { + !ie_match_stat(istate, istate->cache[pos], &st, ce_option)) { /* Nothing changed, really */ free(ce); return 0; -- cgit v1.3 From 8f67f8aefb1b751073f8b36fae8be8f72eb93f4a Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sat, 10 Nov 2007 20:05:14 +0100 Subject: Make the diff_options bitfields be an unsigned with explicit masks. reverse_diff was a bit-value in disguise, it's merged in the flags now. Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- builtin-blame.c | 10 ++--- builtin-diff-files.c | 4 +- builtin-diff-index.c | 4 +- builtin-diff-tree.c | 7 +-- builtin-diff.c | 12 ++--- builtin-log.c | 24 +++++----- combine-diff.c | 10 ++--- diff-lib.c | 24 +++++----- diff.c | 123 +++++++++++++++++++++++++-------------------------- diff.h | 40 ++++++++++------- log-tree.c | 6 +-- merge-recursive.c | 2 +- patch-ids.c | 2 +- revision.c | 22 ++++----- tree-diff.c | 14 +++--- 15 files changed, 155 insertions(+), 149 deletions(-) (limited to 'diff-lib.c') diff --git a/builtin-blame.c b/builtin-blame.c index ba80bf8942..c158d319dc 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -335,7 +335,7 @@ static struct origin *find_origin(struct scoreboard *sb, * same and diff-tree is fairly efficient about this. */ diff_setup(&diff_opts); - diff_opts.recursive = 1; + DIFF_OPT_SET(&diff_opts, RECURSIVE); diff_opts.detect_rename = 0; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; paths[0] = origin->path; @@ -409,7 +409,7 @@ static struct origin *find_rename(struct scoreboard *sb, const char *paths[2]; diff_setup(&diff_opts); - diff_opts.recursive = 1; + DIFF_OPT_SET(&diff_opts, RECURSIVE); diff_opts.detect_rename = DIFF_DETECT_RENAME; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff_opts.single_follow = origin->path; @@ -1075,7 +1075,7 @@ static int find_copy_in_parent(struct scoreboard *sb, return 1; /* nothing remains for this target */ diff_setup(&diff_opts); - diff_opts.recursive = 1; + DIFF_OPT_SET(&diff_opts, RECURSIVE); diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; paths[0] = NULL; @@ -1093,7 +1093,7 @@ static int find_copy_in_parent(struct scoreboard *sb, if ((opt & PICKAXE_BLAME_COPY_HARDEST) || ((opt & PICKAXE_BLAME_COPY_HARDER) && (!porigin || strcmp(target->path, porigin->path)))) - diff_opts.find_copies_harder = 1; + DIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER); if (is_null_sha1(target->commit->object.sha1)) do_diff_cache(parent->tree->object.sha1, &diff_opts); @@ -1102,7 +1102,7 @@ static int find_copy_in_parent(struct scoreboard *sb, target->commit->tree->object.sha1, "", &diff_opts); - if (!diff_opts.find_copies_harder) + if (!DIFF_OPT_TST(&diff_opts, FIND_COPIES_HARDER)) diffcore_std(&diff_opts); retval = 0; diff --git a/builtin-diff-files.c b/builtin-diff-files.c index 6cb30c8e12..046b7e34b5 100644 --- a/builtin-diff-files.c +++ b/builtin-diff-files.c @@ -31,5 +31,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix) if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_RAW; result = run_diff_files_cmd(&rev, argc, argv); - return rev.diffopt.exit_with_status ? rev.diffopt.has_changes: result; + if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS)) + return DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0; + return result; } diff --git a/builtin-diff-index.c b/builtin-diff-index.c index 81e7167438..556c506bfa 100644 --- a/builtin-diff-index.c +++ b/builtin-diff-index.c @@ -44,5 +44,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix) return -1; } result = run_diff_index(&rev, cached); - return rev.diffopt.exit_with_status ? rev.diffopt.has_changes: result; + if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS)) + return DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0; + return result; } diff --git a/builtin-diff-tree.c b/builtin-diff-tree.c index 0b591c8716..2e13716eec 100644 --- a/builtin-diff-tree.c +++ b/builtin-diff-tree.c @@ -118,8 +118,8 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) } if (!read_stdin) - return opt->diffopt.exit_with_status ? - opt->diffopt.has_changes: 0; + return DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS) + && DIFF_OPT_TST(&opt->diffopt, HAS_CHANGES); if (opt->diffopt.detect_rename) opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE | @@ -134,5 +134,6 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) else diff_tree_stdin(line); } - return opt->diffopt.exit_with_status ? opt->diffopt.has_changes: 0; + return DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS) + && DIFF_OPT_TST(&opt->diffopt, HAS_CHANGES); } diff --git a/builtin-diff.c b/builtin-diff.c index f557d21929..1b615991e1 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -35,7 +35,7 @@ static void stuff_change(struct diff_options *opt, !hashcmp(old_sha1, new_sha1) && (old_mode == new_mode)) return; - if (opt->reverse_diff) { + if (DIFF_OPT_TST(opt, REVERSE_DIFF)) { unsigned tmp; const unsigned char *tmp_u; const char *tmp_c; @@ -253,13 +253,13 @@ int cmd_diff(int argc, const char **argv, const char *prefix) if (diff_setup_done(&rev.diffopt) < 0) die("diff_setup_done failed"); } - rev.diffopt.allow_external = 1; - rev.diffopt.recursive = 1; + DIFF_OPT_SET(&rev.diffopt, ALLOW_EXTERNAL); + DIFF_OPT_SET(&rev.diffopt, RECURSIVE); /* If the user asked for our exit code then don't start a * pager or we would end up reporting its exit code instead. */ - if (!rev.diffopt.exit_with_status) + if (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS)) setup_pager(); /* Do we have --cached and not have a pending object, then @@ -363,8 +363,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix) else result = builtin_diff_combined(&rev, argc, argv, ent, ents); - if (rev.diffopt.exit_with_status) - result = rev.diffopt.has_changes; + if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS)) + result = DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0; if (1 < rev.diffopt.skip_stat_unmatch) refresh_index_quietly(); diff --git a/builtin-log.c b/builtin-log.c index 8b2bf632c5..b69b0b42f1 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -55,13 +55,13 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix, rev->abbrev = DEFAULT_ABBREV; rev->commit_format = CMIT_FMT_DEFAULT; rev->verbose_header = 1; - rev->diffopt.recursive = 1; + DIFF_OPT_SET(&rev->diffopt, RECURSIVE); rev->show_root_diff = default_show_root; rev->subject_prefix = fmt_patch_subject_prefix; argc = setup_revisions(argc, argv, rev, "HEAD"); if (rev->diffopt.pickaxe || rev->diffopt.filter) rev->always_show_header = 0; - if (rev->diffopt.follow_renames) { + if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) { rev->always_show_header = 0; if (rev->diffopt.nr_paths != 1) usage("git logs can only follow renames on one pathname at a time"); @@ -185,11 +185,9 @@ int cmd_show(int argc, const char **argv, const char *prefix) struct tag *t = (struct tag *)o; printf("%stag %s%s\n\n", - diff_get_color(rev.diffopt.color_diff, - DIFF_COMMIT), + diff_get_color_opt(&rev.diffopt, DIFF_COMMIT), t->tag, - diff_get_color(rev.diffopt.color_diff, - DIFF_RESET)); + diff_get_color_opt(&rev.diffopt, DIFF_RESET)); ret = show_object(o->sha1, 1); objects[i].item = (struct object *)t->tagged; i--; @@ -197,11 +195,9 @@ int cmd_show(int argc, const char **argv, const char *prefix) } case OBJ_TREE: printf("%stree %s%s\n\n", - diff_get_color(rev.diffopt.color_diff, - DIFF_COMMIT), + diff_get_color_opt(&rev.diffopt, DIFF_COMMIT), name, - diff_get_color(rev.diffopt.color_diff, - DIFF_RESET)); + diff_get_color_opt(&rev.diffopt, DIFF_RESET)); read_tree_recursive((struct tree *)o, "", 0, 0, NULL, show_tree_object); break; @@ -487,7 +483,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) rev.combine_merges = 0; rev.ignore_merges = 1; rev.diffopt.msg_sep = ""; - rev.diffopt.recursive = 1; + DIFF_OPT_SET(&rev.diffopt, RECURSIVE); rev.subject_prefix = fmt_patch_subject_prefix; rev.extra_headers = extra_headers; @@ -590,8 +586,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH; - if (!rev.diffopt.text) - rev.diffopt.binary = 1; + if (!DIFF_OPT_TST(&rev.diffopt, TEXT)) + DIFF_OPT_SET(&rev.diffopt, BINARY); if (!output_directory && !use_stdout) output_directory = prefix; @@ -747,7 +743,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix) revs.diff = 1; revs.combine_merges = 0; revs.ignore_merges = 1; - revs.diffopt.recursive = 1; + DIFF_OPT_SET(&revs.diffopt, RECURSIVE); if (add_pending_commit(head, &revs, 0)) die("Unknown commit %s", head); diff --git a/combine-diff.c b/combine-diff.c index fe5a2a1953..5a658dc0d5 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -664,7 +664,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, int mode_differs = 0; int i, show_hunks; int working_tree_file = is_null_sha1(elem->sha1); - int abbrev = opt->full_index ? 40 : DEFAULT_ABBREV; + int abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? 40 : DEFAULT_ABBREV; mmfile_t result_file; context = opt->context; @@ -784,7 +784,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, if (show_hunks || mode_differs || working_tree_file) { const char *abb; - int use_color = opt->color_diff; + int use_color = DIFF_OPT_TST(opt, COLOR_DIFF); const char *c_meta = diff_get_color(use_color, DIFF_METAINFO); const char *c_reset = diff_get_color(use_color, DIFF_RESET); int added = 0; @@ -836,7 +836,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, dump_quoted_path("+++ /dev/", "null", c_meta, c_reset); else dump_quoted_path("+++ b/", elem->path, c_meta, c_reset); - dump_sline(sline, cnt, num_parent, opt->color_diff); + dump_sline(sline, cnt, num_parent, DIFF_OPT_TST(opt, COLOR_DIFF)); } free(result); @@ -929,8 +929,8 @@ void diff_tree_combined(const unsigned char *sha1, diffopts = *opt; diffopts.output_format = DIFF_FORMAT_NO_OUTPUT; - diffopts.recursive = 1; - diffopts.allow_external = 0; + DIFF_OPT_SET(&diffopts, RECURSIVE); + DIFF_OPT_CLR(&diffopts, ALLOW_EXTERNAL); show_log_first = !!rev->loginfo && !rev->no_commit_id; needsep = 0; diff --git a/diff-lib.c b/diff-lib.c index da5571302d..290a170b05 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -121,7 +121,7 @@ static int queue_diff(struct diff_options *o, } else { struct diff_filespec *d1, *d2; - if (o->reverse_diff) { + if (DIFF_OPT_TST(o, REVERSE_DIFF)) { unsigned tmp; const char *tmp_c; tmp = mode1; mode1 = mode2; mode2 = tmp; @@ -188,8 +188,8 @@ static int handle_diff_files_args(struct rev_info *revs, else if (!strcmp(argv[1], "-n") || !strcmp(argv[1], "--no-index")) { revs->max_count = -2; - revs->diffopt.exit_with_status = 1; - revs->diffopt.no_index = 1; + DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); + DIFF_OPT_SET(&revs->diffopt, NO_INDEX); } else if (!strcmp(argv[1], "-q")) *silent = 1; @@ -207,7 +207,7 @@ static int handle_diff_files_args(struct rev_info *revs, if (!is_in_index(revs->diffopt.paths[0]) || !is_in_index(revs->diffopt.paths[1])) { revs->max_count = -2; - revs->diffopt.no_index = 1; + DIFF_OPT_SET(&revs->diffopt, NO_INDEX); } } @@ -258,7 +258,7 @@ int setup_diff_no_index(struct rev_info *revs, break; } else if (i < argc - 3 && !strcmp(argv[i], "--no-index")) { i = argc - 3; - revs->diffopt.exit_with_status = 1; + DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); break; } if (argc != i + 2 || (!is_outside_repo(argv[i + 1], nongit, prefix) && @@ -296,7 +296,7 @@ int setup_diff_no_index(struct rev_info *revs, else revs->diffopt.paths = argv + argc - 2; revs->diffopt.nr_paths = 2; - revs->diffopt.no_index = 1; + DIFF_OPT_SET(&revs->diffopt, NO_INDEX); revs->max_count = -2; if (diff_setup_done(&revs->diffopt) < 0) die("diff_setup_done failed"); @@ -310,7 +310,7 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) if (handle_diff_files_args(revs, argc, argv, &silent_on_removed)) return -1; - if (revs->diffopt.no_index) { + if (DIFF_OPT_TST(&revs->diffopt, NO_INDEX)) { if (revs->diffopt.nr_paths != 2) return error("need two files/directories with --no-index"); if (queue_diff(&revs->diffopt, revs->diffopt.paths[0], @@ -346,7 +346,8 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed) struct cache_entry *ce = active_cache[i]; int changed; - if (revs->diffopt.quiet && revs->diffopt.has_changes) + if (DIFF_OPT_TST(&revs->diffopt, QUIET) && + DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES)) break; if (!ce_path_match(ce, revs->prune_data)) @@ -442,7 +443,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed) continue; } changed = ce_match_stat(ce, &st, 0); - if (!changed && !revs->diffopt.find_copies_harder) + if (!changed && !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)) continue; oldmode = ntohl(ce->ce_mode); newmode = ntohl(ce_mode_from_stat(ce, st.st_mode)); @@ -561,7 +562,7 @@ static int show_modified(struct rev_info *revs, oldmode = old->ce_mode; if (mode == oldmode && !hashcmp(sha1, old->sha1) && - !revs->diffopt.find_copies_harder) + !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)) return 0; mode = ntohl(mode); @@ -581,7 +582,8 @@ static int diff_cache(struct rev_info *revs, struct cache_entry *ce = *ac; int same = (entries > 1) && ce_same_name(ce, ac[1]); - if (revs->diffopt.quiet && revs->diffopt.has_changes) + if (DIFF_OPT_TST(&revs->diffopt, QUIET) && + DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES)) break; if (!ce_path_match(ce, pathspec)) diff --git a/diff.c b/diff.c index a6aaaf7e5a..67cce8b72e 100644 --- a/diff.c +++ b/diff.c @@ -814,10 +814,10 @@ static void show_stats(struct diffstat_t* data, struct diff_options *options) } /* Find the longest filename and max number of changes */ - reset = diff_get_color(options->color_diff, DIFF_RESET); - set = diff_get_color(options->color_diff, DIFF_PLAIN); - add_c = diff_get_color(options->color_diff, DIFF_FILE_NEW); - del_c = diff_get_color(options->color_diff, DIFF_FILE_OLD); + reset = diff_get_color_opt(options, DIFF_RESET); + set = diff_get_color_opt(options, DIFF_PLAIN); + add_c = diff_get_color_opt(options, DIFF_FILE_NEW); + del_c = diff_get_color_opt(options, DIFF_FILE_OLD); for (i = 0; i < data->nr; i++) { struct diffstat_file *file = data->files[i]; @@ -1243,8 +1243,8 @@ static void builtin_diff(const char *name_a, mmfile_t mf1, mf2; const char *lbl[2]; char *a_one, *b_two; - const char *set = diff_get_color(o->color_diff, DIFF_METAINFO); - const char *reset = diff_get_color(o->color_diff, DIFF_RESET); + const char *set = diff_get_color_opt(o, DIFF_METAINFO); + const char *reset = diff_get_color_opt(o, DIFF_RESET); a_one = quote_two("a/", name_a + (*name_a == '/')); b_two = quote_two("b/", name_b + (*name_b == '/')); @@ -1277,7 +1277,7 @@ static void builtin_diff(const char *name_a, goto free_ab_and_return; if (complete_rewrite) { emit_rewrite_diff(name_a, name_b, one, two, - o->color_diff); + DIFF_OPT_TST(o, COLOR_DIFF)); o->found_changes = 1; goto free_ab_and_return; } @@ -1286,13 +1286,13 @@ static void builtin_diff(const char *name_a, if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0) die("unable to read files to diff"); - if (!o->text && + if (!DIFF_OPT_TST(o, TEXT) && (diff_filespec_is_binary(one) || diff_filespec_is_binary(two))) { /* Quite common confusing case */ if (mf1.size == mf2.size && !memcmp(mf1.ptr, mf2.ptr, mf1.size)) goto free_ab_and_return; - if (o->binary) + if (DIFF_OPT_TST(o, BINARY)) emit_binary_diff(&mf1, &mf2); else printf("Binary files %s and %s differ\n", @@ -1315,7 +1315,7 @@ static void builtin_diff(const char *name_a, memset(&xecfg, 0, sizeof(xecfg)); memset(&ecbdata, 0, sizeof(ecbdata)); ecbdata.label_path = lbl; - ecbdata.color_diff = o->color_diff; + ecbdata.color_diff = DIFF_OPT_TST(o, COLOR_DIFF); ecbdata.found_changesp = &o->found_changes; xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts; xecfg.ctxlen = o->context; @@ -1331,11 +1331,11 @@ static void builtin_diff(const char *name_a, ecb.outf = xdiff_outf; ecb.priv = &ecbdata; ecbdata.xm.consume = fn_out_consume; - if (o->color_diff_words) + if (DIFF_OPT_TST(o, COLOR_DIFF_WORDS)) ecbdata.diff_words = xcalloc(1, sizeof(struct diff_words_data)); xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb); - if (o->color_diff_words) + if (DIFF_OPT_TST(o, COLOR_DIFF_WORDS)) free_diff_words_data(&ecbdata); } @@ -1409,7 +1409,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b, data.xm.consume = checkdiff_consume; data.filename = name_b ? name_b : name_a; data.lineno = 0; - data.color_diff = o->color_diff; + data.color_diff = DIFF_OPT_TST(o, COLOR_DIFF); if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0) die("unable to read files to diff"); @@ -1853,7 +1853,7 @@ static void run_diff_cmd(const char *pgm, struct diff_options *o, int complete_rewrite) { - if (!o->allow_external) + if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL)) pgm = NULL; else { const char *cmd = external_diff_attr(name); @@ -1951,9 +1951,9 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o) } if (hashcmp(one->sha1, two->sha1)) { - int abbrev = o->full_index ? 40 : DEFAULT_ABBREV; + int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV; - if (o->binary) { + if (DIFF_OPT_TST(o, BINARY)) { mmfile_t mf; if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) || (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two))) @@ -2045,7 +2045,10 @@ void diff_setup(struct diff_options *options) options->change = diff_change; options->add_remove = diff_addremove; - options->color_diff = diff_use_color_default; + if (diff_use_color_default) + DIFF_OPT_SET(options, COLOR_DIFF); + else + DIFF_OPT_CLR(options, COLOR_DIFF); options->detect_rename = diff_detect_rename_default; } @@ -2064,7 +2067,7 @@ int diff_setup_done(struct diff_options *options) if (count > 1) die("--name-only, --name-status, --check and -s are mutually exclusive"); - if (options->find_copies_harder) + if (DIFF_OPT_TST(options, FIND_COPIES_HARDER)) options->detect_rename = DIFF_DETECT_COPY; if (options->output_format & (DIFF_FORMAT_NAME | @@ -2088,12 +2091,12 @@ int diff_setup_done(struct diff_options *options) DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_CHECKDIFF)) - options->recursive = 1; + DIFF_OPT_SET(options, RECURSIVE); /* * Also pickaxe would not work very well if you do not say recursive */ if (options->pickaxe) - options->recursive = 1; + DIFF_OPT_SET(options, RECURSIVE); if (options->detect_rename && options->rename_limit < 0) options->rename_limit = diff_rename_limit_default; @@ -2115,9 +2118,9 @@ int diff_setup_done(struct diff_options *options) * to have found. It does not make sense not to return with * exit code in such a case either. */ - if (options->quiet) { + if (DIFF_OPT_TST(options, QUIET)) { options->output_format = DIFF_FORMAT_NO_OUTPUT; - options->exit_with_status = 1; + DIFF_OPT_SET(options, EXIT_WITH_STATUS); } /* @@ -2125,7 +2128,7 @@ int diff_setup_done(struct diff_options *options) * upon the first hit. We need to run diff as usual. */ if (options->pickaxe || options->filter) - options->quiet = 0; + DIFF_OPT_CLR(options, QUIET); return 0; } @@ -2188,15 +2191,12 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) options->output_format |= DIFF_FORMAT_PATCH; else if (!strcmp(arg, "--raw")) options->output_format |= DIFF_FORMAT_RAW; - else if (!strcmp(arg, "--patch-with-raw")) { + else if (!strcmp(arg, "--patch-with-raw")) options->output_format |= DIFF_FORMAT_PATCH | DIFF_FORMAT_RAW; - } - else if (!strcmp(arg, "--numstat")) { + else if (!strcmp(arg, "--numstat")) options->output_format |= DIFF_FORMAT_NUMSTAT; - } - else if (!strcmp(arg, "--shortstat")) { + else if (!strcmp(arg, "--shortstat")) options->output_format |= DIFF_FORMAT_SHORTSTAT; - } else if (!prefixcmp(arg, "--stat")) { char *end; int width = options->stat_width; @@ -2228,33 +2228,30 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) options->output_format |= DIFF_FORMAT_CHECKDIFF; else if (!strcmp(arg, "--summary")) options->output_format |= DIFF_FORMAT_SUMMARY; - else if (!strcmp(arg, "--patch-with-stat")) { + else if (!strcmp(arg, "--patch-with-stat")) options->output_format |= DIFF_FORMAT_PATCH | DIFF_FORMAT_DIFFSTAT; - } else if (!strcmp(arg, "-z")) options->line_termination = 0; else if (!prefixcmp(arg, "-l")) options->rename_limit = strtoul(arg+2, NULL, 10); else if (!strcmp(arg, "--full-index")) - options->full_index = 1; + DIFF_OPT_SET(options, FULL_INDEX); else if (!strcmp(arg, "--binary")) { options->output_format |= DIFF_FORMAT_PATCH; - options->binary = 1; - } - else if (!strcmp(arg, "-a") || !strcmp(arg, "--text")) { - options->text = 1; + DIFF_OPT_SET(options, BINARY); } + else if (!strcmp(arg, "-a") || !strcmp(arg, "--text")) + DIFF_OPT_SET(options, TEXT); else if (!strcmp(arg, "--name-only")) options->output_format |= DIFF_FORMAT_NAME; else if (!strcmp(arg, "--name-status")) options->output_format |= DIFF_FORMAT_NAME_STATUS; else if (!strcmp(arg, "-R")) - options->reverse_diff = 1; + DIFF_OPT_SET(options, REVERSE_DIFF); else if (!prefixcmp(arg, "-S")) options->pickaxe = arg + 2; - else if (!strcmp(arg, "-s")) { + else if (!strcmp(arg, "-s")) options->output_format |= DIFF_FORMAT_NO_OUTPUT; - } else if (!prefixcmp(arg, "-O")) options->orderfile = arg + 2; else if (!prefixcmp(arg, "--diff-filter=")) @@ -2264,28 +2261,25 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) else if (!strcmp(arg, "--pickaxe-regex")) options->pickaxe_opts = DIFF_PICKAXE_REGEX; else if (!prefixcmp(arg, "-B")) { - if ((options->break_opt = - diff_scoreopt_parse(arg)) == -1) + if ((options->break_opt = diff_scoreopt_parse(arg)) == -1) return -1; } else if (!prefixcmp(arg, "-M")) { - if ((options->rename_score = - diff_scoreopt_parse(arg)) == -1) + if ((options->rename_score = diff_scoreopt_parse(arg)) == -1) return -1; options->detect_rename = DIFF_DETECT_RENAME; } else if (!prefixcmp(arg, "-C")) { if (options->detect_rename == DIFF_DETECT_COPY) - options->find_copies_harder = 1; - if ((options->rename_score = - diff_scoreopt_parse(arg)) == -1) + DIFF_OPT_SET(options, FIND_COPIES_HARDER); + if ((options->rename_score = diff_scoreopt_parse(arg)) == -1) return -1; options->detect_rename = DIFF_DETECT_COPY; } else if (!strcmp(arg, "--find-copies-harder")) - options->find_copies_harder = 1; + DIFF_OPT_SET(options, FIND_COPIES_HARDER); else if (!strcmp(arg, "--follow")) - options->follow_renames = 1; + DIFF_OPT_SET(options, FOLLOW_RENAMES); else if (!strcmp(arg, "--abbrev")) options->abbrev = DEFAULT_ABBREV; else if (!prefixcmp(arg, "--abbrev=")) { @@ -2296,9 +2290,9 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) options->abbrev = 40; } else if (!strcmp(arg, "--color")) - options->color_diff = 1; + DIFF_OPT_SET(options, COLOR_DIFF); else if (!strcmp(arg, "--no-color")) - options->color_diff = 0; + DIFF_OPT_CLR(options, COLOR_DIFF); else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space")) options->xdl_opts |= XDF_IGNORE_WHITESPACE; else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change")) @@ -2306,17 +2300,17 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) else if (!strcmp(arg, "--ignore-space-at-eol")) options->xdl_opts |= XDF_IGNORE_WHITESPACE_AT_EOL; else if (!strcmp(arg, "--color-words")) - options->color_diff = options->color_diff_words = 1; + options->flags |= DIFF_OPT_COLOR_DIFF | DIFF_OPT_COLOR_DIFF_WORDS; else if (!strcmp(arg, "--no-renames")) options->detect_rename = 0; else if (!strcmp(arg, "--exit-code")) - options->exit_with_status = 1; + DIFF_OPT_SET(options, EXIT_WITH_STATUS); else if (!strcmp(arg, "--quiet")) - options->quiet = 1; + DIFF_OPT_SET(options, QUIET); else if (!strcmp(arg, "--ext-diff")) - options->allow_external = 1; + DIFF_OPT_SET(options, ALLOW_EXTERNAL); else if (!strcmp(arg, "--no-ext-diff")) - options->allow_external = 0; + DIFF_OPT_CLR(options, ALLOW_EXTERNAL); else return 0; return 1; @@ -3071,7 +3065,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt) * to determine how many paths were dirty only * due to stat info mismatch. */ - if (!diffopt->no_index) + if (!DIFF_OPT_TST(diffopt, NO_INDEX)) diffopt->skip_stat_unmatch++; diff_free_filepair(p); } @@ -3082,10 +3076,10 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt) void diffcore_std(struct diff_options *options) { - if (options->quiet) + if (DIFF_OPT_TST(options, QUIET)) return; - if (options->skip_stat_unmatch && !options->find_copies_harder) + if (options->skip_stat_unmatch && !DIFF_OPT_TST(options, FIND_COPIES_HARDER)) diffcore_skip_stat_unmatch(options); if (options->break_opt != -1) diffcore_break(options->break_opt); @@ -3100,7 +3094,10 @@ void diffcore_std(struct diff_options *options) diff_resolve_rename_copy(); diffcore_apply_filter(options->filter); - options->has_changes = !!diff_queued_diff.nr; + if (diff_queued_diff.nr) + DIFF_OPT_SET(options, HAS_CHANGES); + else + DIFF_OPT_CLR(options, HAS_CHANGES); } @@ -3124,7 +3121,7 @@ void diff_addremove(struct diff_options *options, * Before the final output happens, they are pruned after * merged into rename/copy pairs as appropriate. */ - if (options->reverse_diff) + if (DIFF_OPT_TST(options, REVERSE_DIFF)) addremove = (addremove == '+' ? '-' : addremove == '-' ? '+' : addremove); @@ -3139,7 +3136,7 @@ void diff_addremove(struct diff_options *options, fill_filespec(two, sha1, mode); diff_queue(&diff_queued_diff, one, two); - options->has_changes = 1; + DIFF_OPT_SET(options, HAS_CHANGES); } void diff_change(struct diff_options *options, @@ -3151,7 +3148,7 @@ void diff_change(struct diff_options *options, char concatpath[PATH_MAX]; struct diff_filespec *one, *two; - if (options->reverse_diff) { + if (DIFF_OPT_TST(options, REVERSE_DIFF)) { unsigned tmp; const unsigned char *tmp_c; tmp = old_mode; old_mode = new_mode; new_mode = tmp; @@ -3165,7 +3162,7 @@ void diff_change(struct diff_options *options, fill_filespec(two, new_sha1, new_mode); diff_queue(&diff_queued_diff, one, two); - options->has_changes = 1; + DIFF_OPT_SET(options, HAS_CHANGES); } void diff_unmerge(struct diff_options *options, diff --git a/diff.h b/diff.h index 4546aad219..6ff2b0e318 100644 --- a/diff.h +++ b/diff.h @@ -43,26 +43,32 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q, #define DIFF_FORMAT_CALLBACK 0x1000 +#define DIFF_OPT_RECURSIVE (1 << 0) +#define DIFF_OPT_TREE_IN_RECURSIVE (1 << 1) +#define DIFF_OPT_BINARY (1 << 2) +#define DIFF_OPT_TEXT (1 << 3) +#define DIFF_OPT_FULL_INDEX (1 << 4) +#define DIFF_OPT_SILENT_ON_REMOVE (1 << 5) +#define DIFF_OPT_FIND_COPIES_HARDER (1 << 6) +#define DIFF_OPT_FOLLOW_RENAMES (1 << 7) +#define DIFF_OPT_COLOR_DIFF (1 << 8) +#define DIFF_OPT_COLOR_DIFF_WORDS (1 << 9) +#define DIFF_OPT_HAS_CHANGES (1 << 10) +#define DIFF_OPT_QUIET (1 << 11) +#define DIFF_OPT_NO_INDEX (1 << 12) +#define DIFF_OPT_ALLOW_EXTERNAL (1 << 13) +#define DIFF_OPT_EXIT_WITH_STATUS (1 << 14) +#define DIFF_OPT_REVERSE_DIFF (1 << 15) +#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag) +#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag) +#define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag) + struct diff_options { const char *filter; const char *orderfile; const char *pickaxe; const char *single_follow; - unsigned recursive:1, - tree_in_recursive:1, - binary:1, - text:1, - full_index:1, - silent_on_remove:1, - find_copies_harder:1, - follow_renames:1, - color_diff:1, - color_diff_words:1, - has_changes:1, - quiet:1, - no_index:1, - allow_external:1, - exit_with_status:1; + unsigned flags; int context; int break_opt; int detect_rename; @@ -71,7 +77,6 @@ struct diff_options { int output_format; int pickaxe_opts; int rename_score; - int reverse_diff; int rename_limit; int setup; int abbrev; @@ -105,6 +110,9 @@ enum color_diff { DIFF_WHITESPACE = 7, }; const char *diff_get_color(int diff_use_color, enum color_diff ix); +#define diff_get_color_opt(o, ix) \ + diff_get_color(DIFF_OPT_TST((o), COLOR_DIFF), ix) + extern const char mime_boundary_leader[]; diff --git a/log-tree.c b/log-tree.c index a34beb0b02..1f3fcf16ad 100644 --- a/log-tree.c +++ b/log-tree.c @@ -245,8 +245,7 @@ void show_log(struct rev_info *opt, const char *sep) opt->diffopt.stat_sep = buffer; } } else if (opt->commit_format != CMIT_FMT_USERFORMAT) { - fputs(diff_get_color(opt->diffopt.color_diff, DIFF_COMMIT), - stdout); + fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout); if (opt->commit_format != CMIT_FMT_ONELINE) fputs("commit ", stdout); if (commit->object.flags & BOUNDARY) @@ -266,8 +265,7 @@ void show_log(struct rev_info *opt, const char *sep) diff_unique_abbrev(parent->object.sha1, abbrev_commit)); show_decorations(commit); - printf("%s", - diff_get_color(opt->diffopt.color_diff, DIFF_RESET)); + printf("%s", diff_get_color_opt(&opt->diffopt, DIFF_RESET)); putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n'); if (opt->reflog_info) { show_reflog_message(opt->reflog_info, diff --git a/merge-recursive.c b/merge-recursive.c index 6c6f595fbc..9a1e2f269d 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -366,7 +366,7 @@ static struct path_list *get_renames(struct tree *tree, renames = xcalloc(1, sizeof(struct path_list)); diff_setup(&opts); - opts.recursive = 1; + DIFF_OPT_SET(&opts, RECURSIVE); opts.detect_rename = DIFF_DETECT_RENAME; opts.rename_limit = rename_limit; opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff --git a/patch-ids.c b/patch-ids.c index a288fac992..3be5d3165e 100644 --- a/patch-ids.c +++ b/patch-ids.c @@ -121,7 +121,7 @@ int init_patch_ids(struct patch_ids *ids) { memset(ids, 0, sizeof(*ids)); diff_setup(&ids->diffopts); - ids->diffopts.recursive = 1; + DIFF_OPT_SET(&ids->diffopts, RECURSIVE); if (diff_setup_done(&ids->diffopts) < 0) return error("diff_setup_done failed"); return 0; diff --git a/revision.c b/revision.c index e76da0d448..f5b0e83ee3 100644 --- a/revision.c +++ b/revision.c @@ -250,7 +250,7 @@ static void file_add_remove(struct diff_options *options, } tree_difference = diff; if (tree_difference == REV_TREE_DIFFERENT) - options->has_changes = 1; + DIFF_OPT_SET(options, HAS_CHANGES); } static void file_change(struct diff_options *options, @@ -260,7 +260,7 @@ static void file_change(struct diff_options *options, const char *base, const char *path) { tree_difference = REV_TREE_DIFFERENT; - options->has_changes = 1; + DIFF_OPT_SET(options, HAS_CHANGES); } static int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree *t2) @@ -270,7 +270,7 @@ static int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree if (!t2) return REV_TREE_DIFFERENT; tree_difference = REV_TREE_SAME; - revs->pruning.has_changes = 0; + DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES); if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "", &revs->pruning) < 0) return REV_TREE_DIFFERENT; @@ -294,7 +294,7 @@ static int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1) init_tree_desc(&empty, "", 0); tree_difference = REV_TREE_SAME; - revs->pruning.has_changes = 0; + DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES); retval = diff_tree(&empty, &real, "", &revs->pruning); free(tree); @@ -662,8 +662,8 @@ void init_revisions(struct rev_info *revs, const char *prefix) revs->abbrev = DEFAULT_ABBREV; revs->ignore_merges = 1; revs->simplify_history = 1; - revs->pruning.recursive = 1; - revs->pruning.quiet = 1; + DIFF_OPT_SET(&revs->pruning, RECURSIVE); + DIFF_OPT_SET(&revs->pruning, QUIET); revs->pruning.add_remove = file_add_remove; revs->pruning.change = file_change; revs->lifo = 1; @@ -1054,13 +1054,13 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch } if (!strcmp(arg, "-r")) { revs->diff = 1; - revs->diffopt.recursive = 1; + DIFF_OPT_SET(&revs->diffopt, RECURSIVE); continue; } if (!strcmp(arg, "-t")) { revs->diff = 1; - revs->diffopt.recursive = 1; - revs->diffopt.tree_in_recursive = 1; + DIFF_OPT_SET(&revs->diffopt, RECURSIVE); + DIFF_OPT_SET(&revs->diffopt, TREE_IN_RECURSIVE); continue; } if (!strcmp(arg, "-m")) { @@ -1242,7 +1242,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch revs->diff = 1; /* Pickaxe and rename following needs diffs */ - if (revs->diffopt.pickaxe || revs->diffopt.follow_renames) + if (revs->diffopt.pickaxe || DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES)) revs->diff = 1; if (revs->topo_order) @@ -1251,7 +1251,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch if (revs->prune_data) { diff_tree_setup_paths(revs->prune_data, &revs->pruning); /* Can't prune commits with rename following: the paths change.. */ - if (!revs->diffopt.follow_renames) + if (!DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES)) revs->prune_fn = try_to_simplify_commit; if (!revs->full_diff) diff_tree_setup_paths(revs->prune_data, &revs->diffopt); diff --git a/tree-diff.c b/tree-diff.c index 7c261fd7c3..aa0a100295 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -39,7 +39,7 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const show_entry(opt, "+", t2, base, baselen); return 1; } - if (!opt->find_copies_harder && !hashcmp(sha1, sha2) && mode1 == mode2) + if (!DIFF_OPT_TST(opt, FIND_COPIES_HARDER) && !hashcmp(sha1, sha2) && mode1 == mode2) return 0; /* @@ -52,10 +52,10 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const return 0; } - if (opt->recursive && S_ISDIR(mode1)) { + if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode1)) { int retval; char *newbase = malloc_base(base, baselen, path1, pathlen1); - if (opt->tree_in_recursive) + if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) opt->change(opt, mode1, mode2, sha1, sha2, base, path1); retval = diff_tree_sha1(sha1, sha2, newbase, opt); @@ -206,7 +206,7 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree const char *path; const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode); - if (opt->recursive && S_ISDIR(mode)) { + if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode)) { enum object_type type; int pathlen = tree_entry_len(path, sha1); char *newbase = malloc_base(base, baselen, path, pathlen); @@ -257,7 +257,7 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, stru int baselen = strlen(base); for (;;) { - if (opt->quiet && opt->has_changes) + if (DIFF_OPT_TST(opt, QUIET) && DIFF_OPT_TST(opt, HAS_CHANGES)) break; if (opt->nr_paths) { skip_uninteresting(t1, base, baselen, opt); @@ -315,7 +315,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co q->nr = 0; diff_setup(&diff_opts); - diff_opts.recursive = 1; + DIFF_OPT_SET(&diff_opts, RECURSIVE); diff_opts.detect_rename = DIFF_DETECT_RENAME; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff_opts.single_follow = opt->paths[0]; @@ -380,7 +380,7 @@ int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const cha init_tree_desc(&t1, tree1, size1); init_tree_desc(&t2, tree2, size2); retval = diff_tree(&t1, &t2, base, opt); - if (opt->follow_renames && diff_might_be_rename()) { + if (DIFF_OPT_TST(opt, FOLLOW_RENAMES) && diff_might_be_rename()) { init_tree_desc(&t1, tree1, size1); init_tree_desc(&t2, tree2, size2); try_to_follow_renames(&t1, &t2, base, opt); -- cgit v1.3 From ecf4831d89ba6986249e1bf232b2e2f5f7536223 Mon Sep 17 00:00:00 2001 From: Steffen Prohaska Date: Sun, 25 Nov 2007 23:29:03 +0100 Subject: Use is_absolute_path() in diff-lib.c, lockfile.c, setup.c, trace.c Using the helper function to test for absolute paths makes porting easier. Signed-off-by: Steffen Prohaska Signed-off-by: Junio C Hamano --- diff-lib.c | 2 +- lockfile.c | 2 +- setup.c | 2 +- trace.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index f8e936ae10..d85d8f34ba 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -231,7 +231,7 @@ static int handle_diff_files_args(struct rev_info *revs, static int is_outside_repo(const char *path, int nongit, const char *prefix) { int i; - if (nongit || !strcmp(path, "-") || path[0] == '/') + if (nongit || !strcmp(path, "-") || is_absolute_path(path)) return 1; if (prefixcmp(path, "../")) return 0; diff --git a/lockfile.c b/lockfile.c index 258fb3f5ef..f45d3ed544 100644 --- a/lockfile.c +++ b/lockfile.c @@ -94,7 +94,7 @@ static char *resolve_symlink(char *p, size_t s) return p; } - if (link[0] == '/') { + if (is_absolute_path(link)) { /* absolute path simply replaces p */ if (link_len < s) strcpy(p, link); diff --git a/setup.c b/setup.c index 43cd3f94ea..2c7b5cb200 100644 --- a/setup.c +++ b/setup.c @@ -59,7 +59,7 @@ const char *prefix_path(const char *prefix, int len, const char *path) const char *prefix_filename(const char *pfx, int pfx_len, const char *arg) { static char path[PATH_MAX]; - if (!pfx || !*pfx || arg[0] == '/') + if (!pfx || !*pfx || is_absolute_path(arg)) return arg; memcpy(path, pfx, pfx_len); strcpy(path + pfx_len, arg); diff --git a/trace.c b/trace.c index 0d89dbe779..d3d1b6d55e 100644 --- a/trace.c +++ b/trace.c @@ -37,7 +37,7 @@ static int get_trace_fd(int *need_close) return STDERR_FILENO; if (strlen(trace) == 1 && isdigit(*trace)) return atoi(trace); - if (*trace == '/') { + if (is_absolute_path(trace)) { int fd = open(trace, O_WRONLY | O_APPEND | O_CREAT, 0666); if (fd == -1) { fprintf(stderr, -- cgit v1.3 From 7a51ed66f653c248993b3c4a61932e47933d835e Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 14 Jan 2008 16:03:17 -0800 Subject: Make on-disk index representation separate from in-core one This converts the index explicitly on read and write to its on-disk format, allowing the in-core format to contain more flags, and be simpler. In particular, the in-core format is now host-endian (as opposed to the on-disk one that is network endian in order to be able to be shared across machines) and as a result we can dispense with all the htonl/ntohl on accesses to the cache_entry fields. This will make it easier to make use of various temporary flags that do not exist in the on-disk format. Signed-off-by: Linus Torvalds --- builtin-apply.c | 10 +-- builtin-blame.c | 2 +- builtin-commit.c | 2 +- builtin-fsck.c | 2 +- builtin-grep.c | 4 +- builtin-ls-files.c | 10 +-- builtin-read-tree.c | 3 +- builtin-rerere.c | 4 +- builtin-update-index.c | 18 ++--- cache-tree.c | 4 +- cache.h | 46 ++++++++---- diff-lib.c | 32 ++++---- dir.c | 2 +- entry.c | 6 +- merge-index.c | 2 +- merge-recursive.c | 2 +- reachable.c | 2 +- read-cache.c | 200 +++++++++++++++++++++++++++++-------------------- sha1_name.c | 2 +- tree.c | 4 +- unpack-trees.c | 29 ++++--- 21 files changed, 217 insertions(+), 169 deletions(-) (limited to 'diff-lib.c') diff --git a/builtin-apply.c b/builtin-apply.c index 15432b6782..30d86f2197 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -1946,7 +1946,7 @@ static int read_file_or_gitlink(struct cache_entry *ce, struct strbuf *buf) if (!ce) return 0; - if (S_ISGITLINK(ntohl(ce->ce_mode))) { + if (S_ISGITLINK(ce->ce_mode)) { strbuf_grow(buf, 100); strbuf_addf(buf, "Subproject commit %s\n", sha1_to_hex(ce->sha1)); } else { @@ -2023,7 +2023,7 @@ static int check_to_create_blob(const char *new_name, int ok_if_exists) static int verify_index_match(struct cache_entry *ce, struct stat *st) { - if (S_ISGITLINK(ntohl(ce->ce_mode))) { + if (S_ISGITLINK(ce->ce_mode)) { if (!S_ISDIR(st->st_mode)) return -1; return 0; @@ -2082,12 +2082,12 @@ static int check_patch(struct patch *patch, struct patch *prev_patch) return error("%s: does not match index", old_name); if (cached) - st_mode = ntohl(ce->ce_mode); + st_mode = ce->ce_mode; } else if (stat_ret < 0) return error("%s: %s", old_name, strerror(errno)); if (!cached) - st_mode = ntohl(ce_mode_from_stat(ce, st.st_mode)); + st_mode = ce_mode_from_stat(ce, st.st_mode); if (patch->is_new < 0) patch->is_new = 0; @@ -2388,7 +2388,7 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned ce = xcalloc(1, ce_size); memcpy(ce->name, path, namelen); ce->ce_mode = create_ce_mode(mode); - ce->ce_flags = htons(namelen); + ce->ce_flags = namelen; if (S_ISGITLINK(mode)) { const char *s = buf; diff --git a/builtin-blame.c b/builtin-blame.c index 9b4c02e87f..c7e68874e7 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -2092,7 +2092,7 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con if (!mode) { int pos = cache_name_pos(path, len); if (0 <= pos) - mode = ntohl(active_cache[pos]->ce_mode); + mode = active_cache[pos]->ce_mode; else /* Let's not bother reading from HEAD tree */ mode = S_IFREG | 0644; diff --git a/builtin-commit.c b/builtin-commit.c index 02279360f7..c63ff826fc 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -156,7 +156,7 @@ static int list_paths(struct path_list *list, const char *with_tree, for (i = 0; i < active_nr; i++) { struct cache_entry *ce = active_cache[i]; - if (ce->ce_flags & htons(CE_UPDATE)) + if (ce->ce_flags & CE_UPDATE) continue; if (!pathspec_match(pattern, m, ce->name, 0)) continue; diff --git a/builtin-fsck.c b/builtin-fsck.c index 2a6e94deaf..6fc9525e04 100644 --- a/builtin-fsck.c +++ b/builtin-fsck.c @@ -765,7 +765,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) struct blob *blob; struct object *obj; - mode = ntohl(active_cache[i]->ce_mode); + mode = active_cache[i]->ce_mode; if (S_ISGITLINK(mode)) continue; blob = lookup_blob(active_cache[i]->sha1); diff --git a/builtin-grep.c b/builtin-grep.c index 0d6cc7361f..9180b39e3f 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -331,7 +331,7 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached) struct cache_entry *ce = active_cache[i]; char *name; int kept; - if (!S_ISREG(ntohl(ce->ce_mode))) + if (!S_ISREG(ce->ce_mode)) continue; if (!pathspec_matches(paths, ce->name)) continue; @@ -387,7 +387,7 @@ static int grep_cache(struct grep_opt *opt, const char **paths, int cached) for (nr = 0; nr < active_nr; nr++) { struct cache_entry *ce = active_cache[nr]; - if (!S_ISREG(ntohl(ce->ce_mode))) + if (!S_ISREG(ce->ce_mode)) continue; if (!pathspec_matches(paths, ce->name)) continue; diff --git a/builtin-ls-files.c b/builtin-ls-files.c index 0f0ab2da16..d56e33e251 100644 --- a/builtin-ls-files.c +++ b/builtin-ls-files.c @@ -189,7 +189,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce) return; if (tag && *tag && show_valid_bit && - (ce->ce_flags & htons(CE_VALID))) { + (ce->ce_flags & CE_VALID)) { static char alttag[4]; memcpy(alttag, tag, 3); if (isalpha(tag[0])) @@ -210,7 +210,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce) } else { printf("%s%06o %s %d\t", tag, - ntohl(ce->ce_mode), + ce->ce_mode, abbrev ? find_unique_abbrev(ce->sha1,abbrev) : sha1_to_hex(ce->sha1), ce_stage(ce)); @@ -242,7 +242,7 @@ static void show_files(struct dir_struct *dir, const char *prefix) continue; if (show_unmerged && !ce_stage(ce)) continue; - if (ce->ce_flags & htons(CE_UPDATE)) + if (ce->ce_flags & CE_UPDATE) continue; show_ce_entry(ce_stage(ce) ? tag_unmerged : tag_cached, ce); } @@ -350,7 +350,7 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix) struct cache_entry *ce = active_cache[i]; if (!ce_stage(ce)) continue; - ce->ce_flags |= htons(CE_STAGEMASK); + ce->ce_flags |= CE_STAGEMASK; } if (prefix) { @@ -379,7 +379,7 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix) */ if (last_stage0 && !strcmp(last_stage0->name, ce->name)) - ce->ce_flags |= htons(CE_UPDATE); + ce->ce_flags |= CE_UPDATE; } } } diff --git a/builtin-read-tree.c b/builtin-read-tree.c index c0ea0342b7..5785401753 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -45,8 +45,7 @@ static int read_cache_unmerged(void) continue; cache_tree_invalidate_path(active_cache_tree, ce->name); last = ce; - ce->ce_mode = 0; - ce->ce_flags &= ~htons(CE_STAGEMASK); + ce->ce_flags |= CE_REMOVE; } *dst++ = ce; } diff --git a/builtin-rerere.c b/builtin-rerere.c index a9e3ebc137..b0c17bde87 100644 --- a/builtin-rerere.c +++ b/builtin-rerere.c @@ -149,8 +149,8 @@ static int find_conflict(struct path_list *conflict) if (ce_stage(e2) == 2 && ce_stage(e3) == 3 && ce_same_name(e2, e3) && - S_ISREG(ntohl(e2->ce_mode)) && - S_ISREG(ntohl(e3->ce_mode))) { + S_ISREG(e2->ce_mode) && + S_ISREG(e3->ce_mode)) { path_list_insert((const char *)e2->name, conflict); i++; /* skip over both #2 and #3 */ } diff --git a/builtin-update-index.c b/builtin-update-index.c index c3a14c74ed..a8795d3d5f 100644 --- a/builtin-update-index.c +++ b/builtin-update-index.c @@ -47,10 +47,10 @@ static int mark_valid(const char *path) if (0 <= pos) { switch (mark_valid_only) { case MARK_VALID: - active_cache[pos]->ce_flags |= htons(CE_VALID); + active_cache[pos]->ce_flags |= CE_VALID; break; case UNMARK_VALID: - active_cache[pos]->ce_flags &= ~htons(CE_VALID); + active_cache[pos]->ce_flags &= ~CE_VALID; break; } cache_tree_invalidate_path(active_cache_tree, path); @@ -95,7 +95,7 @@ static int add_one_path(struct cache_entry *old, const char *path, int len, stru size = cache_entry_size(len); ce = xcalloc(1, size); memcpy(ce->name, path, len); - ce->ce_flags = htons(len); + ce->ce_flags = len; fill_stat_cache_info(ce, st); ce->ce_mode = ce_mode_from_stat(old, st->st_mode); @@ -139,7 +139,7 @@ static int process_directory(const char *path, int len, struct stat *st) /* Exact match: file or existing gitlink */ if (pos >= 0) { struct cache_entry *ce = active_cache[pos]; - if (S_ISGITLINK(ntohl(ce->ce_mode))) { + if (S_ISGITLINK(ce->ce_mode)) { /* Do nothing to the index if there is no HEAD! */ if (resolve_gitlink_ref(path, "HEAD", sha1) < 0) @@ -183,7 +183,7 @@ static int process_file(const char *path, int len, struct stat *st) int pos = cache_name_pos(path, len); struct cache_entry *ce = pos < 0 ? NULL : active_cache[pos]; - if (ce && S_ISGITLINK(ntohl(ce->ce_mode))) + if (ce && S_ISGITLINK(ce->ce_mode)) return error("%s is already a gitlink, not replacing", path); return add_one_path(ce, path, len, st); @@ -226,7 +226,7 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1, ce->ce_flags = create_ce_flags(len, stage); ce->ce_mode = create_ce_mode(mode); if (assume_unchanged) - ce->ce_flags |= htons(CE_VALID); + ce->ce_flags |= CE_VALID; option = allow_add ? ADD_CACHE_OK_TO_ADD : 0; option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0; if (add_cache_entry(ce, option)) @@ -246,14 +246,14 @@ static void chmod_path(int flip, const char *path) if (pos < 0) goto fail; ce = active_cache[pos]; - mode = ntohl(ce->ce_mode); + mode = ce->ce_mode; if (!S_ISREG(mode)) goto fail; switch (flip) { case '+': - ce->ce_mode |= htonl(0111); break; + ce->ce_mode |= 0111; break; case '-': - ce->ce_mode &= htonl(~0111); break; + ce->ce_mode &= ~0111; break; default: goto fail; } diff --git a/cache-tree.c b/cache-tree.c index 50b35264fd..bfc95d2dc9 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -320,13 +320,13 @@ static int update_one(struct cache_tree *it, } else { sha1 = ce->sha1; - mode = ntohl(ce->ce_mode); + mode = ce->ce_mode; entlen = pathlen - baselen; } if (mode != S_IFGITLINK && !missing_ok && !has_sha1_file(sha1)) return error("invalid object %s", sha1_to_hex(sha1)); - if (!ce->ce_mode) + if (ce->ce_flags & CE_REMOVE) continue; /* entry being removed */ strbuf_grow(&buffer, entlen + 100); diff --git a/cache.h b/cache.h index 549f4bbac7..4a054c5402 100644 --- a/cache.h +++ b/cache.h @@ -94,48 +94,66 @@ struct cache_time { * We save the fields in big-endian order to allow using the * index file over NFS transparently. */ +struct ondisk_cache_entry { + struct cache_time ctime; + struct cache_time mtime; + unsigned int dev; + unsigned int ino; + unsigned int mode; + unsigned int uid; + unsigned int gid; + unsigned int size; + unsigned char sha1[20]; + unsigned short flags; + char name[FLEX_ARRAY]; /* more */ +}; + struct cache_entry { - struct cache_time ce_ctime; - struct cache_time ce_mtime; + unsigned int ce_ctime; + unsigned int ce_mtime; unsigned int ce_dev; unsigned int ce_ino; unsigned int ce_mode; unsigned int ce_uid; unsigned int ce_gid; unsigned int ce_size; + unsigned int ce_flags; unsigned char sha1[20]; - unsigned short ce_flags; char name[FLEX_ARRAY]; /* more */ }; #define CE_NAMEMASK (0x0fff) #define CE_STAGEMASK (0x3000) -#define CE_UPDATE (0x4000) #define CE_VALID (0x8000) #define CE_STAGESHIFT 12 -#define create_ce_flags(len, stage) htons((len) | ((stage) << CE_STAGESHIFT)) -#define ce_namelen(ce) (CE_NAMEMASK & ntohs((ce)->ce_flags)) +/* In-memory only */ +#define CE_UPDATE (0x10000) +#define CE_REMOVE (0x20000) + +#define create_ce_flags(len, stage) ((len) | ((stage) << CE_STAGESHIFT)) +#define ce_namelen(ce) (CE_NAMEMASK & (ce)->ce_flags) #define ce_size(ce) cache_entry_size(ce_namelen(ce)) -#define ce_stage(ce) ((CE_STAGEMASK & ntohs((ce)->ce_flags)) >> CE_STAGESHIFT) +#define ondisk_ce_size(ce) ondisk_cache_entry_size(ce_namelen(ce)) +#define ce_stage(ce) ((CE_STAGEMASK & (ce)->ce_flags) >> CE_STAGESHIFT) #define ce_permissions(mode) (((mode) & 0100) ? 0755 : 0644) static inline unsigned int create_ce_mode(unsigned int mode) { if (S_ISLNK(mode)) - return htonl(S_IFLNK); + return S_IFLNK; if (S_ISDIR(mode) || S_ISGITLINK(mode)) - return htonl(S_IFGITLINK); - return htonl(S_IFREG | ce_permissions(mode)); + return S_IFGITLINK; + return S_IFREG | ce_permissions(mode); } static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned int mode) { extern int trust_executable_bit, has_symlinks; if (!has_symlinks && S_ISREG(mode) && - ce && S_ISLNK(ntohl(ce->ce_mode))) + ce && S_ISLNK(ce->ce_mode)) return ce->ce_mode; if (!trust_executable_bit && S_ISREG(mode)) { - if (ce && S_ISREG(ntohl(ce->ce_mode))) + if (ce && S_ISREG(ce->ce_mode)) return ce->ce_mode; return create_ce_mode(0666); } @@ -146,14 +164,14 @@ static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned in S_ISLNK(mode) ? S_IFLNK : S_ISDIR(mode) ? S_IFDIR : S_IFGITLINK) #define cache_entry_size(len) ((offsetof(struct cache_entry,name) + (len) + 8) & ~7) +#define ondisk_cache_entry_size(len) ((offsetof(struct ondisk_cache_entry,name) + (len) + 8) & ~7) struct index_state { struct cache_entry **cache; unsigned int cache_nr, cache_alloc, cache_changed; struct cache_tree *cache_tree; time_t timestamp; - void *mmap; - size_t mmap_size; + void *alloc; }; extern struct index_state the_index; diff --git a/diff-lib.c b/diff-lib.c index d85d8f34ba..4a05b02cd0 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -37,7 +37,7 @@ static int get_mode(const char *path, int *mode) if (!path || !strcmp(path, "/dev/null")) *mode = 0; else if (!strcmp(path, "-")) - *mode = ntohl(create_ce_mode(0666)); + *mode = create_ce_mode(0666); else if (stat(path, &st)) return error("Could not access '%s'", path); else @@ -384,7 +384,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) continue; } else - dpath->mode = ntohl(ce_mode_from_stat(ce, st.st_mode)); + dpath->mode = ce_mode_from_stat(ce, st.st_mode); while (i < entries) { struct cache_entry *nce = active_cache[i]; @@ -398,10 +398,10 @@ int run_diff_files(struct rev_info *revs, unsigned int option) */ stage = ce_stage(nce); if (2 <= stage) { - int mode = ntohl(nce->ce_mode); + int mode = nce->ce_mode; num_compare_stages++; hashcpy(dpath->parent[stage-2].sha1, nce->sha1); - dpath->parent[stage-2].mode = ntohl(ce_mode_from_stat(nce, mode)); + dpath->parent[stage-2].mode = ce_mode_from_stat(nce, mode); dpath->parent[stage-2].status = DIFF_STATUS_MODIFIED; } @@ -442,15 +442,15 @@ int run_diff_files(struct rev_info *revs, unsigned int option) } if (silent_on_removed) continue; - diff_addremove(&revs->diffopt, '-', ntohl(ce->ce_mode), + diff_addremove(&revs->diffopt, '-', ce->ce_mode, ce->sha1, ce->name, NULL); continue; } changed = ce_match_stat(ce, &st, ce_option); if (!changed && !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)) continue; - oldmode = ntohl(ce->ce_mode); - newmode = ntohl(ce_mode_from_stat(ce, st.st_mode)); + oldmode = ce->ce_mode; + newmode = ce_mode_from_stat(ce, st.st_mode); diff_change(&revs->diffopt, oldmode, newmode, ce->sha1, (changed ? null_sha1 : ce->sha1), ce->name, NULL); @@ -471,7 +471,7 @@ static void diff_index_show_file(struct rev_info *revs, struct cache_entry *ce, unsigned char *sha1, unsigned int mode) { - diff_addremove(&revs->diffopt, prefix[0], ntohl(mode), + diff_addremove(&revs->diffopt, prefix[0], mode, sha1, ce->name, NULL); } @@ -550,14 +550,14 @@ static int show_modified(struct rev_info *revs, p->len = pathlen; memcpy(p->path, new->name, pathlen); p->path[pathlen] = 0; - p->mode = ntohl(mode); + p->mode = mode; hashclr(p->sha1); memset(p->parent, 0, 2 * sizeof(struct combine_diff_parent)); p->parent[0].status = DIFF_STATUS_MODIFIED; - p->parent[0].mode = ntohl(new->ce_mode); + p->parent[0].mode = new->ce_mode; hashcpy(p->parent[0].sha1, new->sha1); p->parent[1].status = DIFF_STATUS_MODIFIED; - p->parent[1].mode = ntohl(old->ce_mode); + p->parent[1].mode = old->ce_mode; hashcpy(p->parent[1].sha1, old->sha1); show_combined_diff(p, 2, revs->dense_combined_merges, revs); free(p); @@ -569,9 +569,6 @@ static int show_modified(struct rev_info *revs, !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)) return 0; - mode = ntohl(mode); - oldmode = ntohl(oldmode); - diff_change(&revs->diffopt, oldmode, mode, old->sha1, sha1, old->name, NULL); return 0; @@ -628,7 +625,7 @@ static int diff_cache(struct rev_info *revs, cached, match_missing)) break; diff_unmerge(&revs->diffopt, ce->name, - ntohl(ce->ce_mode), ce->sha1); + ce->ce_mode, ce->sha1); break; case 3: diff_unmerge(&revs->diffopt, ce->name, @@ -664,7 +661,7 @@ static void mark_merge_entries(void) struct cache_entry *ce = active_cache[i]; if (!ce_stage(ce)) continue; - ce->ce_flags |= htons(CE_STAGEMASK); + ce->ce_flags |= CE_STAGEMASK; } } @@ -722,8 +719,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) cache_tree_invalidate_path(active_cache_tree, ce->name); last = ce; - ce->ce_mode = 0; - ce->ce_flags &= ~htons(CE_STAGEMASK); + ce->ce_flags |= CE_REMOVE; } *dst++ = ce; } diff --git a/dir.c b/dir.c index 3e345c2fc5..1b9cc7a8a8 100644 --- a/dir.c +++ b/dir.c @@ -391,7 +391,7 @@ static enum exist_status directory_exists_in_index(const char *dirname, int len) break; if (endchar == '/') return index_directory; - if (!endchar && S_ISGITLINK(ntohl(ce->ce_mode))) + if (!endchar && S_ISGITLINK(ce->ce_mode)) return index_gitdir; } return index_nonexistent; diff --git a/entry.c b/entry.c index 257ab46e94..44f4b897d4 100644 --- a/entry.c +++ b/entry.c @@ -103,7 +103,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout int fd; long wrote; - switch (ntohl(ce->ce_mode) & S_IFMT) { + switch (ce->ce_mode & S_IFMT) { char *new; struct strbuf buf; unsigned long size; @@ -129,7 +129,7 @@ static int write_entry(struct cache_entry *ce, char *path, const struct checkout strcpy(path, ".merge_file_XXXXXX"); fd = mkstemp(path); } else - fd = create_file(path, ntohl(ce->ce_mode)); + fd = create_file(path, ce->ce_mode); if (fd < 0) { free(new); return error("git-checkout-index: unable to create file %s (%s)", @@ -221,7 +221,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t unlink(path); if (S_ISDIR(st.st_mode)) { /* If it is a gitlink, leave it alone! */ - if (S_ISGITLINK(ntohl(ce->ce_mode))) + if (S_ISGITLINK(ce->ce_mode)) return 0; if (!state->force) return error("%s is a directory", path); diff --git a/merge-index.c b/merge-index.c index fa719cb0b1..bbb700b54e 100644 --- a/merge-index.c +++ b/merge-index.c @@ -48,7 +48,7 @@ static int merge_entry(int pos, const char *path) break; found++; strcpy(hexbuf[stage], sha1_to_hex(ce->sha1)); - sprintf(ownbuf[stage], "%o", ntohl(ce->ce_mode)); + sprintf(ownbuf[stage], "%o", ce->ce_mode); arguments[stage] = hexbuf[stage]; arguments[stage + 4] = ownbuf[stage]; } while (++pos < active_nr); diff --git a/merge-recursive.c b/merge-recursive.c index c292a77a81..bdf03b1f1f 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -333,7 +333,7 @@ static struct path_list *get_unmerged(void) item->util = xcalloc(1, sizeof(struct stage_data)); } e = item->util; - e->stages[ce_stage(ce)].mode = ntohl(ce->ce_mode); + e->stages[ce_stage(ce)].mode = ce->ce_mode; hashcpy(e->stages[ce_stage(ce)].sha, ce->sha1); } diff --git a/reachable.c b/reachable.c index 6383401e2d..00f289f2f4 100644 --- a/reachable.c +++ b/reachable.c @@ -176,7 +176,7 @@ static void add_cache_refs(struct rev_info *revs) * lookup_blob() on them, to avoid populating the hash table * with invalid information */ - if (S_ISGITLINK(ntohl(active_cache[i]->ce_mode))) + if (S_ISGITLINK(active_cache[i]->ce_mode)) continue; lookup_blob(active_cache[i]->sha1); diff --git a/read-cache.c b/read-cache.c index 7db55883d6..82a6238b77 100644 --- a/read-cache.c +++ b/read-cache.c @@ -30,20 +30,16 @@ struct index_state the_index; */ void fill_stat_cache_info(struct cache_entry *ce, struct stat *st) { - ce->ce_ctime.sec = htonl(st->st_ctime); - ce->ce_mtime.sec = htonl(st->st_mtime); -#ifdef USE_NSEC - ce->ce_ctime.nsec = htonl(st->st_ctim.tv_nsec); - ce->ce_mtime.nsec = htonl(st->st_mtim.tv_nsec); -#endif - ce->ce_dev = htonl(st->st_dev); - ce->ce_ino = htonl(st->st_ino); - ce->ce_uid = htonl(st->st_uid); - ce->ce_gid = htonl(st->st_gid); - ce->ce_size = htonl(st->st_size); + ce->ce_ctime = st->st_ctime; + ce->ce_mtime = st->st_mtime; + ce->ce_dev = st->st_dev; + ce->ce_ino = st->st_ino; + ce->ce_uid = st->st_uid; + ce->ce_gid = st->st_gid; + ce->ce_size = st->st_size; if (assume_unchanged) - ce->ce_flags |= htons(CE_VALID); + ce->ce_flags |= CE_VALID; } static int ce_compare_data(struct cache_entry *ce, struct stat *st) @@ -116,7 +112,7 @@ static int ce_modified_check_fs(struct cache_entry *ce, struct stat *st) return DATA_CHANGED; break; case S_IFDIR: - if (S_ISGITLINK(ntohl(ce->ce_mode))) + if (S_ISGITLINK(ce->ce_mode)) return 0; default: return TYPE_CHANGED; @@ -128,14 +124,17 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st) { unsigned int changed = 0; - switch (ntohl(ce->ce_mode) & S_IFMT) { + if (ce->ce_flags & CE_REMOVE) + return MODE_CHANGED | DATA_CHANGED | TYPE_CHANGED; + + switch (ce->ce_mode & S_IFMT) { case S_IFREG: changed |= !S_ISREG(st->st_mode) ? TYPE_CHANGED : 0; /* We consider only the owner x bit to be relevant for * "mode changes" */ if (trust_executable_bit && - (0100 & (ntohl(ce->ce_mode) ^ st->st_mode))) + (0100 & (ce->ce_mode ^ st->st_mode))) changed |= MODE_CHANGED; break; case S_IFLNK: @@ -149,32 +148,18 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st) else if (ce_compare_gitlink(ce)) changed |= DATA_CHANGED; return changed; - case 0: /* Special case: unmerged file in index */ - return MODE_CHANGED | DATA_CHANGED | TYPE_CHANGED; default: - die("internal error: ce_mode is %o", ntohl(ce->ce_mode)); + die("internal error: ce_mode is %o", ce->ce_mode); } - if (ce->ce_mtime.sec != htonl(st->st_mtime)) - changed |= MTIME_CHANGED; - if (ce->ce_ctime.sec != htonl(st->st_ctime)) - changed |= CTIME_CHANGED; - -#ifdef USE_NSEC - /* - * nsec seems unreliable - not all filesystems support it, so - * as long as it is in the inode cache you get right nsec - * but after it gets flushed, you get zero nsec. - */ - if (ce->ce_mtime.nsec != htonl(st->st_mtim.tv_nsec)) + if (ce->ce_mtime != (unsigned int) st->st_mtime) changed |= MTIME_CHANGED; - if (ce->ce_ctime.nsec != htonl(st->st_ctim.tv_nsec)) + if (ce->ce_ctime != (unsigned int) st->st_ctime) changed |= CTIME_CHANGED; -#endif - if (ce->ce_uid != htonl(st->st_uid) || - ce->ce_gid != htonl(st->st_gid)) + if (ce->ce_uid != (unsigned int) st->st_uid || + ce->ce_gid != (unsigned int) st->st_gid) changed |= OWNER_CHANGED; - if (ce->ce_ino != htonl(st->st_ino)) + if (ce->ce_ino != (unsigned int) st->st_ino) changed |= INODE_CHANGED; #ifdef USE_STDEV @@ -183,11 +168,11 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st) * clients will have different views of what "device" * the filesystem is on */ - if (ce->ce_dev != htonl(st->st_dev)) + if (ce->ce_dev != (unsigned int) st->st_dev) changed |= INODE_CHANGED; #endif - if (ce->ce_size != htonl(st->st_size)) + if (ce->ce_size != (unsigned int) st->st_size) changed |= DATA_CHANGED; return changed; @@ -205,7 +190,7 @@ int ie_match_stat(struct index_state *istate, * If it's marked as always valid in the index, it's * valid whatever the checked-out copy says. */ - if (!ignore_valid && (ce->ce_flags & htons(CE_VALID))) + if (!ignore_valid && (ce->ce_flags & CE_VALID)) return 0; changed = ce_match_stat_basic(ce, st); @@ -228,7 +213,7 @@ int ie_match_stat(struct index_state *istate, */ if (!changed && istate->timestamp && - istate->timestamp <= ntohl(ce->ce_mtime.sec)) { + istate->timestamp <= ce->ce_mtime) { if (assume_racy_is_modified) changed |= DATA_CHANGED; else @@ -257,7 +242,7 @@ int ie_modified(struct index_state *istate, * the length field is zero. For other cases the ce_size * should match the SHA1 recorded in the index entry. */ - if ((changed & DATA_CHANGED) && ce->ce_size != htonl(0)) + if ((changed & DATA_CHANGED) && ce->ce_size != 0) return changed; changed_fs = ce_modified_check_fs(ce, st); @@ -320,7 +305,7 @@ int index_name_pos(struct index_state *istate, const char *name, int namelen) while (last > first) { int next = (last + first) >> 1; struct cache_entry *ce = istate->cache[next]; - int cmp = cache_name_compare(name, namelen, ce->name, ntohs(ce->ce_flags)); + int cmp = cache_name_compare(name, namelen, ce->name, ce->ce_flags); if (!cmp) return next; if (cmp < 0) { @@ -405,7 +390,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose) size = cache_entry_size(namelen); ce = xcalloc(1, size); memcpy(ce->name, path, namelen); - ce->ce_flags = htons(namelen); + ce->ce_flags = namelen; fill_stat_cache_info(ce, &st); if (trust_executable_bit && has_symlinks) @@ -583,7 +568,7 @@ static int has_file_name(struct index_state *istate, continue; if (p->name[len] != '/') continue; - if (!ce_stage(p) && !p->ce_mode) + if (p->ce_flags & CE_REMOVE) continue; retval = -1; if (!ok_to_replace) @@ -616,7 +601,7 @@ static int has_dir_name(struct index_state *istate, } len = slash - name; - pos = index_name_pos(istate, name, ntohs(create_ce_flags(len, stage))); + pos = index_name_pos(istate, name, create_ce_flags(len, stage)); if (pos >= 0) { /* * Found one, but not so fast. This could @@ -679,7 +664,7 @@ static int check_file_directory_conflict(struct index_state *istate, /* * When ce is an "I am going away" entry, we allow it to be added */ - if (!ce_stage(ce) && !ce->ce_mode) + if (ce->ce_flags & CE_REMOVE) return 0; /* @@ -704,7 +689,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK; cache_tree_invalidate_path(istate->cache_tree, ce->name); - pos = index_name_pos(istate, ce->name, ntohs(ce->ce_flags)); + pos = index_name_pos(istate, ce->name, ce->ce_flags); /* existing match? Just replace it. */ if (pos >= 0) { @@ -736,7 +721,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e if (!ok_to_replace) return error("'%s' appears as both a file and as a directory", ce->name); - pos = index_name_pos(istate, ce->name, ntohs(ce->ce_flags)); + pos = index_name_pos(istate, ce->name, ce->ce_flags); pos = -pos-1; } return pos + 1; @@ -810,7 +795,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate, * valid again, under "assume unchanged" mode. */ if (ignore_valid && assume_unchanged && - !(ce->ce_flags & htons(CE_VALID))) + !(ce->ce_flags & CE_VALID)) ; /* mark this one VALID again */ else return ce; @@ -826,7 +811,6 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate, updated = xmalloc(size); memcpy(updated, ce, size); fill_stat_cache_info(updated, &st); - /* * If ignore_valid is not set, we should leave CE_VALID bit * alone. Otherwise, paths marked with --no-assume-unchanged @@ -834,8 +818,8 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate, * automatically, which is not really what we want. */ if (!ignore_valid && assume_unchanged && - !(ce->ce_flags & htons(CE_VALID))) - updated->ce_flags &= ~htons(CE_VALID); + !(ce->ce_flags & CE_VALID)) + updated->ce_flags &= ~CE_VALID; return updated; } @@ -880,7 +864,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p /* If we are doing --really-refresh that * means the index is not valid anymore. */ - ce->ce_flags &= ~htons(CE_VALID); + ce->ce_flags &= ~CE_VALID; istate->cache_changed = 1; } if (quiet) @@ -942,16 +926,34 @@ int read_index(struct index_state *istate) return read_index_from(istate, get_index_file()); } +static void convert_from_disk(struct ondisk_cache_entry *ondisk, struct cache_entry *ce) +{ + ce->ce_ctime = ntohl(ondisk->ctime.sec); + ce->ce_mtime = ntohl(ondisk->mtime.sec); + ce->ce_dev = ntohl(ondisk->dev); + ce->ce_ino = ntohl(ondisk->ino); + ce->ce_mode = ntohl(ondisk->mode); + ce->ce_uid = ntohl(ondisk->uid); + ce->ce_gid = ntohl(ondisk->gid); + ce->ce_size = ntohl(ondisk->size); + /* On-disk flags are just 16 bits */ + ce->ce_flags = ntohs(ondisk->flags); + hashcpy(ce->sha1, ondisk->sha1); + memcpy(ce->name, ondisk->name, ce_namelen(ce)+1); +} + /* remember to discard_cache() before reading a different cache! */ int read_index_from(struct index_state *istate, const char *path) { int fd, i; struct stat st; - unsigned long offset; + unsigned long src_offset, dst_offset; struct cache_header *hdr; + void *mmap; + size_t mmap_size; errno = EBUSY; - if (istate->mmap) + if (istate->alloc) return istate->cache_nr; errno = ENOENT; @@ -967,31 +969,47 @@ int read_index_from(struct index_state *istate, const char *path) die("cannot stat the open index (%s)", strerror(errno)); errno = EINVAL; - istate->mmap_size = xsize_t(st.st_size); - if (istate->mmap_size < sizeof(struct cache_header) + 20) + mmap_size = xsize_t(st.st_size); + if (mmap_size < sizeof(struct cache_header) + 20) die("index file smaller than expected"); - istate->mmap = xmmap(NULL, istate->mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); close(fd); + if (mmap == MAP_FAILED) + die("unable to map index file"); - hdr = istate->mmap; - if (verify_hdr(hdr, istate->mmap_size) < 0) + hdr = mmap; + if (verify_hdr(hdr, mmap_size) < 0) goto unmap; istate->cache_nr = ntohl(hdr->hdr_entries); istate->cache_alloc = alloc_nr(istate->cache_nr); istate->cache = xcalloc(istate->cache_alloc, sizeof(struct cache_entry *)); - offset = sizeof(*hdr); + /* + * The disk format is actually larger than the in-memory format, + * due to space for nsec etc, so even though the in-memory one + * has room for a few more flags, we can allocate using the same + * index size + */ + istate->alloc = xmalloc(mmap_size); + + src_offset = sizeof(*hdr); + dst_offset = 0; for (i = 0; i < istate->cache_nr; i++) { + struct ondisk_cache_entry *disk_ce; struct cache_entry *ce; - ce = (struct cache_entry *)((char *)(istate->mmap) + offset); - offset = offset + ce_size(ce); + disk_ce = (struct ondisk_cache_entry *)((char *)mmap + src_offset); + ce = (struct cache_entry *)((char *)istate->alloc + dst_offset); + convert_from_disk(disk_ce, ce); istate->cache[i] = ce; + + src_offset += ondisk_ce_size(ce); + dst_offset += ce_size(ce); } istate->timestamp = st.st_mtime; - while (offset <= istate->mmap_size - 20 - 8) { + while (src_offset <= mmap_size - 20 - 8) { /* After an array of active_nr index entries, * there can be arbitrary number of extended * sections, each of which is prefixed with @@ -999,40 +1017,36 @@ int read_index_from(struct index_state *istate, const char *path) * in 4-byte network byte order. */ unsigned long extsize; - memcpy(&extsize, (char *)(istate->mmap) + offset + 4, 4); + memcpy(&extsize, (char *)mmap + src_offset + 4, 4); extsize = ntohl(extsize); if (read_index_extension(istate, - ((const char *) (istate->mmap)) + offset, - (char *) (istate->mmap) + offset + 8, + (const char *) mmap + src_offset, + (char *) mmap + src_offset + 8, extsize) < 0) goto unmap; - offset += 8; - offset += extsize; + src_offset += 8; + src_offset += extsize; } + munmap(mmap, mmap_size); return istate->cache_nr; unmap: - munmap(istate->mmap, istate->mmap_size); + munmap(mmap, mmap_size); errno = EINVAL; die("index file corrupt"); } int discard_index(struct index_state *istate) { - int ret; - istate->cache_nr = 0; istate->cache_changed = 0; istate->timestamp = 0; cache_tree_free(&(istate->cache_tree)); - if (istate->mmap == NULL) - return 0; - ret = munmap(istate->mmap, istate->mmap_size); - istate->mmap = NULL; - istate->mmap_size = 0; + free(istate->alloc); + istate->alloc = NULL; /* no need to throw away allocated active_cache */ - return ret; + return 0; } #define WRITE_BUFFER_SIZE 8192 @@ -1144,10 +1158,32 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce) * file, and never calls us, so the cached size information * for "frotz" stays 6 which does not match the filesystem. */ - ce->ce_size = htonl(0); + ce->ce_size = 0; } } +static int ce_write_entry(SHA_CTX *c, int fd, struct cache_entry *ce) +{ + int size = ondisk_ce_size(ce); + struct ondisk_cache_entry *ondisk = xcalloc(1, size); + + ondisk->ctime.sec = htonl(ce->ce_ctime); + ondisk->ctime.nsec = 0; + ondisk->mtime.sec = htonl(ce->ce_mtime); + ondisk->mtime.nsec = 0; + ondisk->dev = htonl(ce->ce_dev); + ondisk->ino = htonl(ce->ce_ino); + ondisk->mode = htonl(ce->ce_mode); + ondisk->uid = htonl(ce->ce_uid); + ondisk->gid = htonl(ce->ce_gid); + ondisk->size = htonl(ce->ce_size); + hashcpy(ondisk->sha1, ce->sha1); + ondisk->flags = htons(ce->ce_flags); + memcpy(ondisk->name, ce->name, ce_namelen(ce)); + + return ce_write(c, fd, ondisk, size); +} + int write_index(struct index_state *istate, int newfd) { SHA_CTX c; @@ -1157,7 +1193,7 @@ int write_index(struct index_state *istate, int newfd) int entries = istate->cache_nr; for (i = removed = 0; i < entries; i++) - if (!cache[i]->ce_mode) + if (cache[i]->ce_flags & CE_REMOVE) removed++; hdr.hdr_signature = htonl(CACHE_SIGNATURE); @@ -1170,12 +1206,12 @@ int write_index(struct index_state *istate, int newfd) for (i = 0; i < entries; i++) { struct cache_entry *ce = cache[i]; - if (!ce->ce_mode) + if (ce->ce_flags & CE_REMOVE) continue; if (istate->timestamp && - istate->timestamp <= ntohl(ce->ce_mtime.sec)) + istate->timestamp <= ce->ce_mtime) ce_smudge_racily_clean_entry(ce); - if (ce_write(&c, newfd, ce, ce_size(ce)) < 0) + if (ce_write_entry(&c, newfd, ce) < 0) return -1; } diff --git a/sha1_name.c b/sha1_name.c index 13e11645e1..be8489e4e5 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -695,7 +695,7 @@ int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode) break; if (ce_stage(ce) == stage) { hashcpy(sha1, ce->sha1); - *mode = ntohl(ce->ce_mode); + *mode = ce->ce_mode; return 0; } pos++; diff --git a/tree.c b/tree.c index 8c0819fa72..87708ef420 100644 --- a/tree.c +++ b/tree.c @@ -142,8 +142,8 @@ static int cmp_cache_name_compare(const void *a_, const void *b_) ce1 = *((const struct cache_entry **)a_); ce2 = *((const struct cache_entry **)b_); - return cache_name_compare(ce1->name, ntohs(ce1->ce_flags), - ce2->name, ntohs(ce2->ce_flags)); + return cache_name_compare(ce1->name, ce1->ce_flags, + ce2->name, ce2->ce_flags); } int read_tree(struct tree *tree, int stage, const char **match) diff --git a/unpack-trees.c b/unpack-trees.c index aa2513ed79..ff46fd62fd 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -289,7 +289,6 @@ static struct checkout state; static void check_updates(struct cache_entry **src, int nr, struct unpack_trees_options *o) { - unsigned short mask = htons(CE_UPDATE); unsigned cnt = 0, total = 0; struct progress *progress = NULL; char last_symlink[PATH_MAX]; @@ -297,7 +296,7 @@ static void check_updates(struct cache_entry **src, int nr, if (o->update && o->verbose_update) { for (total = cnt = 0; cnt < nr; cnt++) { struct cache_entry *ce = src[cnt]; - if (!ce->ce_mode || ce->ce_flags & mask) + if (ce->ce_flags & (CE_UPDATE | CE_REMOVE)) total++; } @@ -310,15 +309,15 @@ static void check_updates(struct cache_entry **src, int nr, while (nr--) { struct cache_entry *ce = *src++; - if (!ce->ce_mode || ce->ce_flags & mask) + if (ce->ce_flags & (CE_UPDATE | CE_REMOVE)) display_progress(progress, ++cnt); - if (!ce->ce_mode) { + if (ce->ce_flags & CE_REMOVE) { if (o->update) unlink_entry(ce->name, last_symlink); continue; } - if (ce->ce_flags & mask) { - ce->ce_flags &= ~mask; + if (ce->ce_flags & CE_UPDATE) { + ce->ce_flags &= ~CE_UPDATE; if (o->update) { checkout_entry(ce, &state, NULL); *last_symlink = '\0'; @@ -408,7 +407,7 @@ static void verify_uptodate(struct cache_entry *ce, * submodules that are marked to be automatically * checked out. */ - if (S_ISGITLINK(ntohl(ce->ce_mode))) + if (S_ISGITLINK(ce->ce_mode)) return; errno = 0; } @@ -450,7 +449,7 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action, int cnt = 0; unsigned char sha1[20]; - if (S_ISGITLINK(ntohl(ce->ce_mode)) && + if (S_ISGITLINK(ce->ce_mode) && resolve_gitlink_ref(ce->name, "HEAD", sha1) == 0) { /* If we are not going to update the submodule, then * we don't care. @@ -481,7 +480,7 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action, */ if (!ce_stage(ce)) { verify_uptodate(ce, o); - ce->ce_mode = 0; + ce->ce_flags |= CE_REMOVE; } cnt++; } @@ -568,7 +567,7 @@ static void verify_absent(struct cache_entry *ce, const char *action, cnt = cache_name_pos(ce->name, strlen(ce->name)); if (0 <= cnt) { struct cache_entry *ce = active_cache[cnt]; - if (!ce_stage(ce) && !ce->ce_mode) + if (ce->ce_flags & CE_REMOVE) return; } @@ -580,7 +579,7 @@ static void verify_absent(struct cache_entry *ce, const char *action, static int merged_entry(struct cache_entry *merge, struct cache_entry *old, struct unpack_trees_options *o) { - merge->ce_flags |= htons(CE_UPDATE); + merge->ce_flags |= CE_UPDATE; if (old) { /* * See if we can re-use the old CE directly? @@ -601,7 +600,7 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old, invalidate_ce_path(merge); } - merge->ce_flags &= ~htons(CE_STAGEMASK); + merge->ce_flags &= ~CE_STAGEMASK; add_cache_entry(merge, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); return 1; } @@ -613,7 +612,7 @@ static int deleted_entry(struct cache_entry *ce, struct cache_entry *old, verify_uptodate(old, o); else verify_absent(ce, "removed", o); - ce->ce_mode = 0; + ce->ce_flags |= CE_REMOVE; add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); invalidate_ce_path(ce); return 1; @@ -634,7 +633,7 @@ static void show_stage_entry(FILE *o, else fprintf(o, "%s%06o %s %d\t%s\n", label, - ntohl(ce->ce_mode), + ce->ce_mode, sha1_to_hex(ce->sha1), ce_stage(ce), ce->name); @@ -920,7 +919,7 @@ int oneway_merge(struct cache_entry **src, struct stat st; if (lstat(old->name, &st) || ce_match_stat(old, &st, CE_MATCH_IGNORE_VALID)) - old->ce_flags |= htons(CE_UPDATE); + old->ce_flags |= CE_UPDATE; } return keep_entry(old, o); } -- cgit v1.3 From d1f2d7e8ca65504722108e2db710788f66c34c6c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 19 Jan 2008 17:27:12 -0800 Subject: Make run_diff_index() use unpack_trees(), not read_tree() A plain "git commit" would still run lstat() a lot more than necessary, because wt_status_print() would cause the index to be repeatedly flushed and re-read by wt_read_cache(), and that would cause the CE_UPTODATE bit to be lost, resulting in the files in the index being lstat'ed three times each. The reason why wt-status.c ended up invalidating and re-reading the cache multiple times was that it uses "run_diff_index()", which in turn uses "read_tree()" to populate the index with *both* the old index and the tree we want to compare against. So this patch re-writes run_diff_index() to not use read_tree(), but instead use "unpack_trees()" to diff the index to a tree. That, in turn, means that we don't need to modify the index itself, which then means that we don't need to invalidate it and re-read it! This, together with the lstat() optimizations, means that "git commit" on the kernel tree really only needs to lstat() the index entries once. That noticeably cuts down on the cached timings. Best time before: [torvalds@woody linux]$ time git commit > /dev/null real 0m0.399s user 0m0.232s sys 0m0.164s Best time after: [torvalds@woody linux]$ time git commit > /dev/null real 0m0.254s user 0m0.140s sys 0m0.112s so it's a noticeable improvement in addition to being a nice conceptual cleanup (it's really not that pretty that "run_diff_index()" dirties the index!) Doing an "strace -c" on it also shows that as it cuts the number of lstat() calls by two thirds, it goes from being lstat()-limited to being limited by getdents() (which is the readdir system call): Before: % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 60.69 0.000704 0 69230 31 lstat 23.62 0.000274 0 5522 getdents 8.36 0.000097 0 5508 2638 open 2.59 0.000030 0 2869 close 2.50 0.000029 0 274 write 1.47 0.000017 0 2844 fstat After: % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 45.17 0.000276 0 5522 getdents 26.51 0.000162 0 23112 31 lstat 19.80 0.000121 0 5503 2638 open 4.91 0.000030 0 2864 close 1.48 0.000020 0 274 write 1.34 0.000018 0 2844 fstat ... It passes the test-suite for me, but this is another of one of those really core functions, and certainly pretty subtle, so.. NOTE! The Linux lstat() system call is really quite cheap when everything is cached, so the fact that this is quite noticeable on Linux is likely to mean that it is *much* more noticeable on other operating systems. I bet you'll see a much bigger performance improvement from this on Windows in particular. Signed-off-by: Linus Torvalds --- diff-lib.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++------ unpack-trees.h | 1 + wt-status.c | 10 ---- 3 files changed, 138 insertions(+), 24 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index 4a05b02cd0..045f3cc58e 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -9,6 +9,7 @@ #include "revision.h" #include "cache-tree.h" #include "path-list.h" +#include "unpack-trees.h" /* * diff-files @@ -435,6 +436,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option) continue; } + if (ce_uptodate(ce)) + continue; if (lstat(ce->name, &st) < 0) { if (errno != ENOENT && errno != ENOTDIR) { perror(ce->name); @@ -665,20 +668,133 @@ static void mark_merge_entries(void) } } -int run_diff_index(struct rev_info *revs, int cached) +/* + * This gets a mix of an existing index and a tree, one pathname entry + * at a time. The index entry may be a single stage-0 one, but it could + * also be multiple unmerged entries (in which case idx_pos/idx_nr will + * give you the position and number of entries in the index). + */ +static void do_oneway_diff(struct unpack_trees_options *o, + struct cache_entry *idx, + struct cache_entry *tree, + int idx_pos, int idx_nr) { - int ret; - struct object *ent; - struct tree *tree; - const char *tree_name; - int match_missing = 0; + struct rev_info *revs = o->unpack_data; + int match_missing, cached; /* * Backward compatibility wart - "diff-index -m" does - * not mean "do not ignore merges", but totally different. + * not mean "do not ignore merges", but "match_missing". + * + * But with the revision flag parsing, that's found in + * "!revs->ignore_merges". + */ + cached = o->index_only; + match_missing = !revs->ignore_merges; + + if (cached && idx && ce_stage(idx)) { + if (tree) + diff_unmerge(&revs->diffopt, idx->name, idx->ce_mode, idx->sha1); + return; + } + + /* + * Something added to the tree? + */ + if (!tree) { + show_new_file(revs, idx, cached, match_missing); + return; + } + + /* + * Something removed from the tree? */ - if (!revs->ignore_merges) - match_missing = 1; + if (!idx) { + diff_index_show_file(revs, "-", tree, tree->sha1, tree->ce_mode); + return; + } + + /* Show difference between old and new */ + show_modified(revs, tree, idx, 1, cached, match_missing); +} + +/* + * Count how many index entries go with the first one + */ +static inline int count_skip(const struct cache_entry *src, int pos) +{ + int skip = 1; + + /* We can only have multiple entries if the first one is not stage-0 */ + if (ce_stage(src)) { + struct cache_entry **p = active_cache + pos; + int namelen = ce_namelen(src); + + for (;;) { + const struct cache_entry *ce; + pos++; + if (pos >= active_nr) + break; + ce = *++p; + if (ce_namelen(ce) != namelen) + break; + if (memcmp(ce->name, src->name, namelen)) + break; + skip++; + } + } + return skip; +} + +/* + * The unpack_trees() interface is designed for merging, so + * the different source entries are designed primarily for + * the source trees, with the old index being really mainly + * used for being replaced by the result. + * + * For diffing, the index is more important, and we only have a + * single tree. + * + * We're supposed to return how many index entries we want to skip. + * + * This wrapper makes it all more readable, and takes care of all + * the fairly complex unpack_trees() semantic requirements, including + * the skipping, the path matching, the type conflict cases etc. + */ +static int oneway_diff(struct cache_entry **src, + struct unpack_trees_options *o, + int index_pos) +{ + int skip = 0; + struct cache_entry *idx = src[0]; + struct cache_entry *tree = src[1]; + struct rev_info *revs = o->unpack_data; + + if (index_pos >= 0) + skip = count_skip(idx, index_pos); + + /* + * Unpack-trees generates a DF/conflict entry if + * there was a directory in the index and a tree + * in the tree. From a diff standpoint, that's a + * delete of the tree and a create of the file. + */ + if (tree == o->df_conflict_entry) + tree = NULL; + + if (ce_path_match(idx ? idx : tree, revs->prune_data)) + do_oneway_diff(o, idx, tree, index_pos, skip); + + return skip; +} + +int run_diff_index(struct rev_info *revs, int cached) +{ + struct object *ent; + struct tree *tree; + const char *tree_name; + struct unpack_trees_options opts; + struct tree_desc t; mark_merge_entries(); @@ -687,13 +803,20 @@ int run_diff_index(struct rev_info *revs, int cached) tree = parse_tree_indirect(ent->sha1); if (!tree) return error("bad tree object %s", tree_name); - if (read_tree(tree, 1, revs->prune_data)) - return error("unable to read tree object %s", tree_name); - ret = diff_cache(revs, active_cache, active_nr, revs->prune_data, - cached, match_missing); + + memset(&opts, 0, sizeof(opts)); + opts.head_idx = 1; + opts.index_only = cached; + opts.merge = 1; + opts.fn = oneway_diff; + opts.unpack_data = revs; + + init_tree_desc(&t, tree->buffer, tree->size); + unpack_trees(1, &t, &opts); + diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); - return ret; + return 0; } int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) diff --git a/unpack-trees.h b/unpack-trees.h index 5517faafad..197a0044aa 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -25,6 +25,7 @@ struct unpack_trees_options { int merge_size; struct cache_entry *df_conflict_entry; + void *unpack_data; }; extern int unpack_trees(unsigned n, struct tree_desc *t, diff --git a/wt-status.c b/wt-status.c index c0c247243b..27b946d552 100644 --- a/wt-status.c +++ b/wt-status.c @@ -217,19 +217,12 @@ static void wt_status_print_changed_cb(struct diff_queue_struct *q, wt_status_print_trailer(s); } -static void wt_read_cache(struct wt_status *s) -{ - discard_cache(); - read_cache_from(s->index_file); -} - static void wt_status_print_initial(struct wt_status *s) { int i; struct strbuf buf; strbuf_init(&buf, 0); - wt_read_cache(s); if (active_nr) { s->commitable = 1; wt_status_print_cached_header(s); @@ -256,7 +249,6 @@ static void wt_status_print_updated(struct wt_status *s) rev.diffopt.detect_rename = 1; rev.diffopt.rename_limit = 100; rev.diffopt.break_opt = 0; - wt_read_cache(s); run_diff_index(&rev, 1); } @@ -268,7 +260,6 @@ static void wt_status_print_changed(struct wt_status *s) rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK; rev.diffopt.format_callback = wt_status_print_changed_cb; rev.diffopt.format_callback_data = s; - wt_read_cache(s); run_diff_files(&rev, 0); } @@ -335,7 +326,6 @@ static void wt_status_print_verbose(struct wt_status *s) setup_revisions(0, NULL, &rev, s->reference); rev.diffopt.output_format |= DIFF_FORMAT_PATCH; rev.diffopt.detect_rename = 1; - wt_read_cache(s); run_diff_index(&rev, 1); fflush(stdout); -- cgit v1.3 From 204ce979a5ed6f182e56bea5282c7b4a2d91208a Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 20 Jan 2008 15:19:56 +0000 Subject: Also use unpack_trees() in do_diff_cache() As in run_diff_index(), we call unpack_trees() with the oneway_diff() function in do_diff_cache() now. This makes the function diff_cache() obsolete. Signed-off-by: Johannes Schindelin Signed-off-by: Linus Torvalds --- diff-lib.c | 92 +++++++++----------------------------------------------------- 1 file changed, 13 insertions(+), 79 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index 045f3cc58e..03eaa7cef3 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -577,81 +577,6 @@ static int show_modified(struct rev_info *revs, return 0; } -static int diff_cache(struct rev_info *revs, - struct cache_entry **ac, int entries, - const char **pathspec, - int cached, int match_missing) -{ - while (entries) { - struct cache_entry *ce = *ac; - int same = (entries > 1) && ce_same_name(ce, ac[1]); - - if (DIFF_OPT_TST(&revs->diffopt, QUIET) && - DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES)) - break; - - if (!ce_path_match(ce, pathspec)) - goto skip_entry; - - switch (ce_stage(ce)) { - case 0: - /* No stage 1 entry? That means it's a new file */ - if (!same) { - show_new_file(revs, ce, cached, match_missing); - break; - } - /* Show difference between old and new */ - show_modified(revs, ac[1], ce, 1, - cached, match_missing); - break; - case 1: - /* No stage 3 (merge) entry? - * That means it's been deleted. - */ - if (!same) { - diff_index_show_file(revs, "-", ce, - ce->sha1, ce->ce_mode); - break; - } - /* We come here with ce pointing at stage 1 - * (original tree) and ac[1] pointing at stage - * 3 (unmerged). show-modified with - * report-missing set to false does not say the - * file is deleted but reports true if work - * tree does not have it, in which case we - * fall through to report the unmerged state. - * Otherwise, we show the differences between - * the original tree and the work tree. - */ - if (!cached && - !show_modified(revs, ce, ac[1], 0, - cached, match_missing)) - break; - diff_unmerge(&revs->diffopt, ce->name, - ce->ce_mode, ce->sha1); - break; - case 3: - diff_unmerge(&revs->diffopt, ce->name, - 0, null_sha1); - break; - - default: - die("impossible cache entry stage"); - } - -skip_entry: - /* - * Ignore all the different stages for this file, - * we've handled the relevant cases now. - */ - do { - ac++; - entries--; - } while (entries && ce_same_name(ce, ac[0])); - } - return 0; -} - /* * This turns all merge entries into "stage 3". That guarantees that * when we read in the new tree (into "stage 1"), we won't lose sight @@ -826,6 +751,8 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) int i; struct cache_entry **dst; struct cache_entry *last = NULL; + struct unpack_trees_options opts; + struct tree_desc t; /* * This is used by git-blame to run diff-cache internally; @@ -853,8 +780,15 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) tree = parse_tree_indirect(tree_sha1); if (!tree) die("bad tree object %s", sha1_to_hex(tree_sha1)); - if (read_tree(tree, 1, opt->paths)) - return error("unable to read tree %s", sha1_to_hex(tree_sha1)); - return diff_cache(&revs, active_cache, active_nr, revs.prune_data, - 1, 0); + + memset(&opts, 0, sizeof(opts)); + opts.head_idx = 1; + opts.index_only = 1; + opts.merge = 1; + opts.fn = oneway_diff; + opts.unpack_data = &revs; + + init_tree_desc(&t, tree->buffer, tree->size); + unpack_trees(1, &t, &opts); + return 0; } -- cgit v1.3 From 203a2fe117070964a5bf7cc940a742cad7a19fca Mon Sep 17 00:00:00 2001 From: Daniel Barkalow Date: Thu, 7 Feb 2008 11:39:48 -0500 Subject: Allow callers of unpack_trees() to handle failure Return an error from unpack_trees() instead of calling die(), and exit with an error in read-tree, builtin-commit, and diff-lib. merge-recursive already expected an error return from unpack_trees, so it doesn't need to be changed. The merge function can return negative to abort. This will be used in builtin-checkout -m. Signed-off-by: Daniel Barkalow --- builtin-commit.c | 3 +- builtin-read-tree.c | 3 +- diff-lib.c | 6 ++-- unpack-trees.c | 85 ++++++++++++++++++++++++++++++----------------------- 4 files changed, 56 insertions(+), 41 deletions(-) (limited to 'diff-lib.c') diff --git a/builtin-commit.c b/builtin-commit.c index c63ff826fc..5b5b7c0f4d 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -200,7 +200,8 @@ static void create_base_index(void) die("failed to unpack HEAD tree object"); parse_tree(tree); init_tree_desc(&t, tree->buffer, tree->size); - unpack_trees(1, &t, &opts); + if (unpack_trees(1, &t, &opts)) + exit(128); /* We've already reported the error, finish dying */ } static char *prepare_index(int argc, const char **argv, const char *prefix) diff --git a/builtin-read-tree.c b/builtin-read-tree.c index 5785401753..1d9d125b91 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -268,7 +268,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) parse_tree(tree); init_tree_desc(t+i, tree->buffer, tree->size); } - unpack_trees(nr_trees, t, &opts); + if (unpack_trees(nr_trees, t, &opts)) + return 128; /* * When reading only one tree (either the most basic form, diff --git a/diff-lib.c b/diff-lib.c index 03eaa7cef3..94b150e830 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -737,7 +737,8 @@ int run_diff_index(struct rev_info *revs, int cached) opts.unpack_data = revs; init_tree_desc(&t, tree->buffer, tree->size); - unpack_trees(1, &t, &opts); + if (unpack_trees(1, &t, &opts)) + exit(128); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); @@ -789,6 +790,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) opts.unpack_data = &revs; init_tree_desc(&t, tree->buffer, tree->size); - unpack_trees(1, &t, &opts); + if (unpack_trees(1, &t, &opts)) + exit(128); return 0; } diff --git a/unpack-trees.c b/unpack-trees.c index ff46fd62fd..9e6587f661 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -219,6 +219,8 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len, } #endif ret = o->fn(src, o, remove); + if (ret < 0) + return ret; #if DBRT_DEBUG > 1 printf("Added %d entries\n", ret); @@ -359,7 +361,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options } if (o->trivial_merges_only && o->nontrivial_merge) - die("Merge requires file-level merging"); + return error("Merge requires file-level merging"); check_updates(active_cache, active_nr, o); return 0; @@ -367,10 +369,10 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options /* Here come the merge functions */ -static void reject_merge(struct cache_entry *ce) +static int reject_merge(struct cache_entry *ce) { - die("Entry '%s' would be overwritten by merge. Cannot merge.", - ce->name); + return error("Entry '%s' would be overwritten by merge. Cannot merge.", + ce->name); } static int same(struct cache_entry *a, struct cache_entry *b) @@ -388,18 +390,18 @@ static int same(struct cache_entry *a, struct cache_entry *b) * When a CE gets turned into an unmerged entry, we * want it to be up-to-date */ -static void verify_uptodate(struct cache_entry *ce, +static int verify_uptodate(struct cache_entry *ce, struct unpack_trees_options *o) { struct stat st; if (o->index_only || o->reset) - return; + return 0; if (!lstat(ce->name, &st)) { unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID); if (!changed) - return; + return 0; /* * NEEDSWORK: the current default policy is to allow * submodule to be out of sync wrt the supermodule @@ -408,12 +410,12 @@ static void verify_uptodate(struct cache_entry *ce, * checked out. */ if (S_ISGITLINK(ce->ce_mode)) - return; + return 0; errno = 0; } if (errno == ENOENT) - return; - die("Entry '%s' not uptodate. Cannot merge.", ce->name); + return 0; + return error("Entry '%s' not uptodate. Cannot merge.", ce->name); } static void invalidate_ce_path(struct cache_entry *ce) @@ -479,7 +481,8 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action, * ce->name is an entry in the subdirectory. */ if (!ce_stage(ce)) { - verify_uptodate(ce, o); + if (verify_uptodate(ce, o)) + return -1; ce->ce_flags |= CE_REMOVE; } cnt++; @@ -498,8 +501,8 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action, d.exclude_per_dir = o->dir->exclude_per_dir; i = read_directory(&d, ce->name, pathbuf, namelen+1, NULL); if (i) - die("Updating '%s' would lose untracked files in it", - ce->name); + return error("Updating '%s' would lose untracked files in it", + ce->name); free(pathbuf); return cnt; } @@ -508,16 +511,16 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action, * We do not want to remove or overwrite a working tree file that * is not tracked, unless it is ignored. */ -static void verify_absent(struct cache_entry *ce, const char *action, - struct unpack_trees_options *o) +static int verify_absent(struct cache_entry *ce, const char *action, + struct unpack_trees_options *o) { struct stat st; if (o->index_only || o->reset || !o->update) - return; + return 0; if (has_symlink_leading_path(ce->name, NULL)) - return; + return 0; if (!lstat(ce->name, &st)) { int cnt; @@ -527,7 +530,7 @@ static void verify_absent(struct cache_entry *ce, const char *action, * ce->name is explicitly excluded, so it is Ok to * overwrite it. */ - return; + return 0; if (S_ISDIR(st.st_mode)) { /* * We are checking out path "foo" and @@ -556,7 +559,7 @@ static void verify_absent(struct cache_entry *ce, const char *action, * deleted entries here. */ o->pos += cnt; - return; + return 0; } /* @@ -568,12 +571,13 @@ static void verify_absent(struct cache_entry *ce, const char *action, if (0 <= cnt) { struct cache_entry *ce = active_cache[cnt]; if (ce->ce_flags & CE_REMOVE) - return; + return 0; } - die("Untracked working tree file '%s' " - "would be %s by merge.", ce->name, action); + return error("Untracked working tree file '%s' " + "would be %s by merge.", ce->name, action); } + return 0; } static int merged_entry(struct cache_entry *merge, struct cache_entry *old, @@ -591,12 +595,14 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old, if (same(old, merge)) { memcpy(merge, old, offsetof(struct cache_entry, name)); } else { - verify_uptodate(old, o); + if (verify_uptodate(old, o)) + return -1; invalidate_ce_path(old); } } else { - verify_absent(merge, "overwritten", o); + if (verify_absent(merge, "overwritten", o)) + return -1; invalidate_ce_path(merge); } @@ -608,10 +614,12 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old, static int deleted_entry(struct cache_entry *ce, struct cache_entry *old, struct unpack_trees_options *o) { - if (old) - verify_uptodate(old, o); - else - verify_absent(ce, "removed", o); + if (old) { + if (verify_uptodate(old, o)) + return -1; + } else + if (verify_absent(ce, "removed", o)) + return -1; ce->ce_flags |= CE_REMOVE; add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); invalidate_ce_path(ce); @@ -699,7 +707,7 @@ int threeway_merge(struct cache_entry **stages, /* #14, #14ALT, #2ALT */ if (remote && !df_conflict_head && head_match && !remote_match) { if (index && !same(index, remote) && !same(index, head)) - reject_merge(index); + return reject_merge(index); return merged_entry(remote, index, o); } /* @@ -707,7 +715,7 @@ int threeway_merge(struct cache_entry **stages, * make sure that it matches head. */ if (index && !same(index, head)) { - reject_merge(index); + return reject_merge(index); } if (head) { @@ -758,8 +766,10 @@ int threeway_merge(struct cache_entry **stages, remove_entry(remove); if (index) return deleted_entry(index, index, o); - else if (ce && !head_deleted) - verify_absent(ce, "removed", o); + else if (ce && !head_deleted) { + if (verify_absent(ce, "removed", o)) + return -1; + } return 0; } /* @@ -775,7 +785,8 @@ int threeway_merge(struct cache_entry **stages, * conflict resolution files. */ if (index) { - verify_uptodate(index, o); + if (verify_uptodate(index, o)) + return -1; } remove_entry(remove); @@ -855,11 +866,11 @@ int twoway_merge(struct cache_entry **src, /* all other failures */ remove_entry(remove); if (oldtree) - reject_merge(oldtree); + return reject_merge(oldtree); if (current) - reject_merge(current); + return reject_merge(current); if (newtree) - reject_merge(newtree); + return reject_merge(newtree); return -1; } } @@ -886,7 +897,7 @@ int bind_merge(struct cache_entry **src, return error("Cannot do a bind merge of %d trees\n", o->merge_size); if (a && old) - die("Entry '%s' overlaps. Cannot bind.", a->name); + return error("Entry '%s' overlaps. Cannot bind.", a->name); if (!a) return keep_entry(old, o); else -- cgit v1.3 From c8c16f2865f7c9c0d59b31ce66d50a4ecae72fd0 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 2 Mar 2008 00:57:26 -0800 Subject: diff-lib.c: constness strengthening The internal implementation of diff-index codepath used to use non const pointer to pass sha1 around, but it did not have to. With this, we can also lose the private no_sha1[] array, as we can use the public null_sha1[] array that exists exactly for the same purpose. Signed-off-by: Junio C Hamano --- diff-lib.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index 94b150e830..4581b594d0 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -472,22 +472,21 @@ int run_diff_files(struct rev_info *revs, unsigned int option) static void diff_index_show_file(struct rev_info *revs, const char *prefix, struct cache_entry *ce, - unsigned char *sha1, unsigned int mode) + const unsigned char *sha1, unsigned int mode) { diff_addremove(&revs->diffopt, prefix[0], mode, sha1, ce->name, NULL); } static int get_stat_data(struct cache_entry *ce, - unsigned char **sha1p, + const unsigned char **sha1p, unsigned int *modep, int cached, int match_missing) { - unsigned char *sha1 = ce->sha1; + const unsigned char *sha1 = ce->sha1; unsigned int mode = ce->ce_mode; if (!cached) { - static unsigned char no_sha1[20]; int changed; struct stat st; if (lstat(ce->name, &st) < 0) { @@ -501,7 +500,7 @@ static int get_stat_data(struct cache_entry *ce, changed = ce_match_stat(ce, &st, 0); if (changed) { mode = ce_mode_from_stat(ce, st.st_mode); - sha1 = no_sha1; + sha1 = null_sha1; } } @@ -514,7 +513,7 @@ static void show_new_file(struct rev_info *revs, struct cache_entry *new, int cached, int match_missing) { - unsigned char *sha1; + const unsigned char *sha1; unsigned int mode; /* New file in the index: it might actually be different in @@ -533,7 +532,7 @@ static int show_modified(struct rev_info *revs, int cached, int match_missing) { unsigned int mode, oldmode; - unsigned char *sha1; + const unsigned char *sha1; if (get_stat_data(new, &sha1, &mode, cached, match_missing) < 0) { if (report_missing) -- cgit v1.3 From bc052d7f435f8f729127cc4790484865c1a974b9 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 6 Mar 2008 12:26:14 -0800 Subject: Make 'unpack_trees()' take the index to work on as an argument This is just a very mechanical conversion, and makes everybody set it to '&the_index' before calling, but at least it makes it more explicit where we work with the index. The next stage would be to split that index usage up into a 'source' and a 'destination' index, so that we can unpack into a different index than we started out from. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- builtin-checkout.c | 6 ++++ builtin-commit.c | 1 + builtin-merge-recursive.c | 1 + builtin-read-tree.c | 1 + diff-lib.c | 2 ++ unpack-trees.c | 79 ++++++++++++++++++++++++----------------------- unpack-trees.h | 1 + 7 files changed, 52 insertions(+), 39 deletions(-) (limited to 'diff-lib.c') diff --git a/builtin-checkout.c b/builtin-checkout.c index 6b08016228..9bdb6233f0 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -152,6 +152,7 @@ static int reset_to_new(struct tree *tree, int quiet) { struct unpack_trees_options opts; struct tree_desc tree_desc; + memset(&opts, 0, sizeof(opts)); opts.head_idx = -1; opts.update = 1; @@ -159,6 +160,7 @@ static int reset_to_new(struct tree *tree, int quiet) opts.merge = 1; opts.fn = oneway_merge; opts.verbose_update = !quiet; + opts.index = &the_index; parse_tree(tree); init_tree_desc(&tree_desc, tree->buffer, tree->size); if (unpack_trees(1, &tree_desc, &opts)) @@ -170,6 +172,7 @@ static void reset_clean_to_new(struct tree *tree, int quiet) { struct unpack_trees_options opts; struct tree_desc tree_desc; + memset(&opts, 0, sizeof(opts)); opts.head_idx = -1; opts.skip_unmerged = 1; @@ -177,6 +180,7 @@ static void reset_clean_to_new(struct tree *tree, int quiet) opts.merge = 1; opts.fn = oneway_merge; opts.verbose_update = !quiet; + opts.index = &the_index; parse_tree(tree); init_tree_desc(&tree_desc, tree->buffer, tree->size); if (unpack_trees(1, &tree_desc, &opts)) @@ -224,8 +228,10 @@ static int merge_working_tree(struct checkout_opts *opts, struct tree_desc trees[2]; struct tree *tree; struct unpack_trees_options topts; + memset(&topts, 0, sizeof(topts)); topts.head_idx = -1; + topts.index = &the_index; refresh_cache(REFRESH_QUIET); diff --git a/builtin-commit.c b/builtin-commit.c index f49c22e642..38a542258a 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -198,6 +198,7 @@ static void create_base_index(void) opts.head_idx = 1; opts.index_only = 1; opts.merge = 1; + opts.index = &the_index; opts.fn = oneway_merge; tree = parse_tree_indirect(head_sha1); diff --git a/builtin-merge-recursive.c b/builtin-merge-recursive.c index 6fe4102c0c..50b389623c 100644 --- a/builtin-merge-recursive.c +++ b/builtin-merge-recursive.c @@ -213,6 +213,7 @@ static int git_merge_trees(int index_only, opts.merge = 1; opts.head_idx = 2; opts.fn = threeway_merge; + opts.index = &the_index; init_tree_desc_from_tree(t+0, common); init_tree_desc_from_tree(t+1, head); diff --git a/builtin-read-tree.c b/builtin-read-tree.c index 0138f5a917..d004e90431 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -102,6 +102,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) memset(&opts, 0, sizeof(opts)); opts.head_idx = -1; + opts.index = &the_index; git_config(git_default_config); diff --git a/diff-lib.c b/diff-lib.c index 4581b594d0..e359058d0b 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -734,6 +734,7 @@ int run_diff_index(struct rev_info *revs, int cached) opts.merge = 1; opts.fn = oneway_diff; opts.unpack_data = revs; + opts.index = &the_index; init_tree_desc(&t, tree->buffer, tree->size); if (unpack_trees(1, &t, &opts)) @@ -787,6 +788,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) opts.merge = 1; opts.fn = oneway_diff; opts.unpack_data = &revs; + opts.index = &the_index; init_tree_desc(&t, tree->buffer, tree->size); if (unpack_trees(1, &t, &opts)) diff --git a/unpack-trees.c b/unpack-trees.c index ee9be29374..cb8f847968 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1,3 +1,4 @@ +#define NO_THE_INDEX_COMPATIBILITY_MACROS #include "cache.h" #include "dir.h" #include "tree.h" @@ -7,10 +8,10 @@ #include "progress.h" #include "refs.h" -static inline void remove_entry(int remove) +static inline void remove_entry(int remove, struct unpack_trees_options *o) { if (remove >= 0) - remove_cache_entry_at(remove); + remove_index_entry_at(o->index, remove); } /* Unlink the last component and attempt to remove leading @@ -53,8 +54,8 @@ static void check_updates(struct unpack_trees_options *o) int i; if (o->update && o->verbose_update) { - for (total = cnt = 0; cnt < active_nr; cnt++) { - struct cache_entry *ce = active_cache[cnt]; + for (total = cnt = 0; cnt < o->index->cache_nr; cnt++) { + struct cache_entry *ce = o->index->cache[cnt]; if (ce->ce_flags & (CE_UPDATE | CE_REMOVE)) total++; } @@ -65,15 +66,15 @@ static void check_updates(struct unpack_trees_options *o) } *last_symlink = '\0'; - for (i = 0; i < active_nr; i++) { - struct cache_entry *ce = active_cache[i]; + for (i = 0; i < o->index->cache_nr; i++) { + struct cache_entry *ce = o->index->cache[i]; if (ce->ce_flags & (CE_UPDATE | CE_REMOVE)) display_progress(progress, ++cnt); if (ce->ce_flags & CE_REMOVE) { if (o->update) unlink_entry(ce->name, last_symlink); - remove_cache_entry_at(i); + remove_index_entry_at(o->index, i); i--; continue; } @@ -105,7 +106,7 @@ static int unpack_index_entry(struct cache_entry *ce, struct unpack_trees_option if (o->skip_unmerged) { o->pos++; } else { - remove_entry(o->pos); + remove_entry(o->pos, o); } return 0; } @@ -242,9 +243,9 @@ static int unpack_nondirectories(int n, unsigned long mask, unsigned long dirmas return call_unpack_fn(src, o, remove); n += o->merge; - remove_entry(remove); + remove_entry(remove, o); for (i = 0; i < n; i++) - add_cache_entry(src[i], ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK); + add_index_entry(o->index, src[i], ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK); return 0; } @@ -261,8 +262,8 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str /* Are we supposed to look at the index too? */ if (o->merge) { - while (o->pos < active_nr) { - struct cache_entry *ce = active_cache[o->pos]; + while (o->pos < o->index->cache_nr) { + struct cache_entry *ce = o->index->cache[o->pos]; int cmp = compare_entry(ce, info, p); if (cmp < 0) { if (unpack_index_entry(ce, o) < 0) @@ -277,7 +278,7 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str */ if (o->skip_unmerged) return mask; - remove_entry(o->pos); + remove_entry(o->pos, o); continue; } src[0] = ce; @@ -312,8 +313,8 @@ static int unpack_failed(struct unpack_trees_options *o, const char *message) return error(message); return -1; } - discard_cache(); - read_cache(); + discard_index(o->index); + read_index(o->index); return -1; } @@ -349,8 +350,8 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options /* Any left-over entries in the index? */ if (o->merge) { - while (o->pos < active_nr) { - struct cache_entry *ce = active_cache[o->pos]; + while (o->pos < o->index->cache_nr) { + struct cache_entry *ce = o->index->cache[o->pos]; if (unpack_index_entry(ce, o) < 0) return unpack_failed(o, NULL); } @@ -395,7 +396,7 @@ static int verify_uptodate(struct cache_entry *ce, return 0; if (!lstat(ce->name, &st)) { - unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID); + unsigned changed = ie_match_stat(o->index, ce, &st, CE_MATCH_IGNORE_VALID); if (!changed) return 0; /* @@ -415,10 +416,10 @@ static int verify_uptodate(struct cache_entry *ce, error("Entry '%s' not uptodate. Cannot merge.", ce->name); } -static void invalidate_ce_path(struct cache_entry *ce) +static void invalidate_ce_path(struct cache_entry *ce, struct unpack_trees_options *o) { if (ce) - cache_tree_invalidate_path(active_cache_tree, ce->name); + cache_tree_invalidate_path(o->index->cache_tree, ce->name); } /* @@ -463,12 +464,12 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action, * in that directory. */ namelen = strlen(ce->name); - pos = cache_name_pos(ce->name, namelen); + pos = index_name_pos(o->index, ce->name, namelen); if (0 <= pos) return cnt; /* we have it as nondirectory */ pos = -pos - 1; - for (i = pos; i < active_nr; i++) { - struct cache_entry *ce = active_cache[i]; + for (i = pos; i < o->index->cache_nr; i++) { + struct cache_entry *ce = o->index->cache[i]; int len = ce_namelen(ce); if (len < namelen || strncmp(ce->name, ce->name, namelen) || @@ -566,9 +567,9 @@ static int verify_absent(struct cache_entry *ce, const char *action, * delete this path, which is in a subdirectory that * is being replaced with a blob. */ - cnt = cache_name_pos(ce->name, strlen(ce->name)); + cnt = index_name_pos(o->index, ce->name, strlen(ce->name)); if (0 <= cnt) { - struct cache_entry *ce = active_cache[cnt]; + struct cache_entry *ce = o->index->cache[cnt]; if (ce->ce_flags & CE_REMOVE) return 0; } @@ -597,17 +598,17 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old, } else { if (verify_uptodate(old, o)) return -1; - invalidate_ce_path(old); + invalidate_ce_path(old, o); } } else { if (verify_absent(merge, "overwritten", o)) return -1; - invalidate_ce_path(merge); + invalidate_ce_path(merge, o); } merge->ce_flags &= ~CE_STAGEMASK; - add_cache_entry(merge, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); + add_index_entry(o->index, merge, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); return 1; } @@ -621,14 +622,14 @@ static int deleted_entry(struct cache_entry *ce, struct cache_entry *old, if (verify_absent(ce, "removed", o)) return -1; ce->ce_flags |= CE_REMOVE; - add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); - invalidate_ce_path(ce); + add_index_entry(o->index, ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); + invalidate_ce_path(ce, o); return 1; } static int keep_entry(struct cache_entry *ce, struct unpack_trees_options *o) { - add_cache_entry(ce, ADD_CACHE_OK_TO_ADD); + add_index_entry(o->index, ce, ADD_CACHE_OK_TO_ADD); return 1; } @@ -728,7 +729,7 @@ int threeway_merge(struct cache_entry **stages, /* #1 */ if (!head && !remote && any_anc_missing) { - remove_entry(remove); + remove_entry(remove, o); return 0; } @@ -762,7 +763,7 @@ int threeway_merge(struct cache_entry **stages, if ((head_deleted && remote_deleted) || (head_deleted && remote && remote_match) || (remote_deleted && head && head_match)) { - remove_entry(remove); + remove_entry(remove, o); if (index) return deleted_entry(index, index, o); else if (ce && !head_deleted) { @@ -788,7 +789,7 @@ int threeway_merge(struct cache_entry **stages, return -1; } - remove_entry(remove); + remove_entry(remove, o); o->nontrivial_merge = 1; /* #2, #3, #4, #6, #7, #9, #10, #11. */ @@ -853,7 +854,7 @@ int twoway_merge(struct cache_entry **src, } else if (oldtree && !newtree && same(current, oldtree)) { /* 10 or 11 */ - remove_entry(remove); + remove_entry(remove, o); return deleted_entry(oldtree, current, o); } else if (oldtree && newtree && @@ -863,7 +864,7 @@ int twoway_merge(struct cache_entry **src, } else { /* all other failures */ - remove_entry(remove); + remove_entry(remove, o); if (oldtree) return o->gently ? -1 : reject_merge(oldtree); if (current) @@ -875,7 +876,7 @@ int twoway_merge(struct cache_entry **src, } else if (newtree) return merged_entry(newtree, current, o); - remove_entry(remove); + remove_entry(remove, o); return deleted_entry(oldtree, current, o); } @@ -922,14 +923,14 @@ int oneway_merge(struct cache_entry **src, o->merge_size); if (!a) { - remove_entry(remove); + remove_entry(remove, o); return deleted_entry(old, old, o); } if (old && same(old, a)) { if (o->reset) { struct stat st; if (lstat(old->name, &st) || - ce_match_stat(old, &st, CE_MATCH_IGNORE_VALID)) + ie_match_stat(o->index, old, &st, CE_MATCH_IGNORE_VALID)) old->ce_flags |= CE_UPDATE; } return keep_entry(old, o); diff --git a/unpack-trees.h b/unpack-trees.h index a2df544d04..65add1652f 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -28,6 +28,7 @@ struct unpack_trees_options { struct cache_entry *df_conflict_entry; void *unpack_data; + struct index_state *index; }; extern int unpack_trees(unsigned n, struct tree_desc *t, -- cgit v1.3 From 34110cd4e394e3f92c01a4709689b384c34645d8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 6 Mar 2008 18:12:28 -0800 Subject: Make 'unpack_trees()' have a separate source and destination index We will always unpack into our own internal index, but we will take the source from wherever specified, and we will optionally write the result to a specified index (optionally, because not everybody even _wants_ any result: the index diffing really wants to just walk the tree and index in parallel). This ends up removing a fair number more lines than it adds, for the simple reason that we can now skip all the crud that tried to be oh-so-careful about maintaining our position in the index as we were traversing and modifying it. Since we don't actually modify the source index any more, we can just update the 'o->pos' pointer without worrying about whether an index entry got removed or replaced or added to. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- builtin-checkout.c | 9 ++- builtin-commit.c | 3 +- builtin-merge-recursive.c | 3 +- builtin-read-tree.c | 24 +------- diff-lib.c | 49 +++------------ t/t1005-read-tree-reset.sh | 2 +- unpack-trees.c | 149 ++++++++++++++++++++++----------------------- unpack-trees.h | 16 ++--- 8 files changed, 102 insertions(+), 153 deletions(-) (limited to 'diff-lib.c') diff --git a/builtin-checkout.c b/builtin-checkout.c index 9bdb6233f0..7deb504837 100644 --- a/builtin-checkout.c +++ b/builtin-checkout.c @@ -160,7 +160,8 @@ static int reset_to_new(struct tree *tree, int quiet) opts.merge = 1; opts.fn = oneway_merge; opts.verbose_update = !quiet; - opts.index = &the_index; + opts.src_index = &the_index; + opts.dst_index = &the_index; parse_tree(tree); init_tree_desc(&tree_desc, tree->buffer, tree->size); if (unpack_trees(1, &tree_desc, &opts)) @@ -180,7 +181,8 @@ static void reset_clean_to_new(struct tree *tree, int quiet) opts.merge = 1; opts.fn = oneway_merge; opts.verbose_update = !quiet; - opts.index = &the_index; + opts.src_index = &the_index; + opts.dst_index = &the_index; parse_tree(tree); init_tree_desc(&tree_desc, tree->buffer, tree->size); if (unpack_trees(1, &tree_desc, &opts)) @@ -231,7 +233,8 @@ static int merge_working_tree(struct checkout_opts *opts, memset(&topts, 0, sizeof(topts)); topts.head_idx = -1; - topts.index = &the_index; + topts.src_index = &the_index; + topts.dst_index = &the_index; refresh_cache(REFRESH_QUIET); diff --git a/builtin-commit.c b/builtin-commit.c index 38a542258a..660a3458f7 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -198,7 +198,8 @@ static void create_base_index(void) opts.head_idx = 1; opts.index_only = 1; opts.merge = 1; - opts.index = &the_index; + opts.src_index = &the_index; + opts.dst_index = &the_index; opts.fn = oneway_merge; tree = parse_tree_indirect(head_sha1); diff --git a/builtin-merge-recursive.c b/builtin-merge-recursive.c index 50b389623c..fa02bb5a80 100644 --- a/builtin-merge-recursive.c +++ b/builtin-merge-recursive.c @@ -213,7 +213,8 @@ static int git_merge_trees(int index_only, opts.merge = 1; opts.head_idx = 2; opts.fn = threeway_merge; - opts.index = &the_index; + opts.src_index = &the_index; + opts.dst_index = &the_index; init_tree_desc_from_tree(t+0, common); init_tree_desc_from_tree(t+1, head); diff --git a/builtin-read-tree.c b/builtin-read-tree.c index d004e90431..160456dad1 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -102,7 +102,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) memset(&opts, 0, sizeof(opts)); opts.head_idx = -1; - opts.index = &the_index; + opts.src_index = &the_index; + opts.dst_index = &the_index; git_config(git_default_config); @@ -221,27 +222,6 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) if ((opts.dir && !opts.update)) die("--exclude-per-directory is meaningless unless -u"); - if (opts.prefix) { - int pfxlen = strlen(opts.prefix); - int pos; - if (opts.prefix[pfxlen-1] != '/') - die("prefix must end with /"); - if (stage != 2) - die("binding merge takes only one tree"); - pos = cache_name_pos(opts.prefix, pfxlen); - if (0 <= pos) - die("corrupt index file"); - pos = -pos-1; - if (pos < active_nr && - !strncmp(active_cache[pos]->name, opts.prefix, pfxlen)) - die("subdirectory '%s' already exists.", opts.prefix); - pos = cache_name_pos(opts.prefix, pfxlen-1); - if (0 <= pos) - die("file '%.*s' already exists.", - pfxlen-1, opts.prefix); - opts.pos = -1 - pos; - } - if (opts.merge) { if (stage < 2) die("just how do you expect me to merge %d trees?", stage-1); diff --git a/diff-lib.c b/diff-lib.c index e359058d0b..9520773f3b 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -600,8 +600,7 @@ static void mark_merge_entries(void) */ static void do_oneway_diff(struct unpack_trees_options *o, struct cache_entry *idx, - struct cache_entry *tree, - int idx_pos, int idx_nr) + struct cache_entry *tree) { struct rev_info *revs = o->unpack_data; int match_missing, cached; @@ -642,34 +641,6 @@ static void do_oneway_diff(struct unpack_trees_options *o, show_modified(revs, tree, idx, 1, cached, match_missing); } -/* - * Count how many index entries go with the first one - */ -static inline int count_skip(const struct cache_entry *src, int pos) -{ - int skip = 1; - - /* We can only have multiple entries if the first one is not stage-0 */ - if (ce_stage(src)) { - struct cache_entry **p = active_cache + pos; - int namelen = ce_namelen(src); - - for (;;) { - const struct cache_entry *ce; - pos++; - if (pos >= active_nr) - break; - ce = *++p; - if (ce_namelen(ce) != namelen) - break; - if (memcmp(ce->name, src->name, namelen)) - break; - skip++; - } - } - return skip; -} - /* * The unpack_trees() interface is designed for merging, so * the different source entries are designed primarily for @@ -685,18 +656,12 @@ static inline int count_skip(const struct cache_entry *src, int pos) * the fairly complex unpack_trees() semantic requirements, including * the skipping, the path matching, the type conflict cases etc. */ -static int oneway_diff(struct cache_entry **src, - struct unpack_trees_options *o, - int index_pos) +static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o) { - int skip = 0; struct cache_entry *idx = src[0]; struct cache_entry *tree = src[1]; struct rev_info *revs = o->unpack_data; - if (index_pos >= 0) - skip = count_skip(idx, index_pos); - /* * Unpack-trees generates a DF/conflict entry if * there was a directory in the index and a tree @@ -707,9 +672,9 @@ static int oneway_diff(struct cache_entry **src, tree = NULL; if (ce_path_match(idx ? idx : tree, revs->prune_data)) - do_oneway_diff(o, idx, tree, index_pos, skip); + do_oneway_diff(o, idx, tree); - return skip; + return 0; } int run_diff_index(struct rev_info *revs, int cached) @@ -734,7 +699,8 @@ int run_diff_index(struct rev_info *revs, int cached) opts.merge = 1; opts.fn = oneway_diff; opts.unpack_data = revs; - opts.index = &the_index; + opts.src_index = &the_index; + opts.dst_index = NULL; init_tree_desc(&t, tree->buffer, tree->size); if (unpack_trees(1, &t, &opts)) @@ -788,7 +754,8 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) opts.merge = 1; opts.fn = oneway_diff; opts.unpack_data = &revs; - opts.index = &the_index; + opts.src_index = &the_index; + opts.dst_index = &the_index; init_tree_desc(&t, tree->buffer, tree->size); if (unpack_trees(1, &t, &opts)) diff --git a/t/t1005-read-tree-reset.sh b/t/t1005-read-tree-reset.sh index f1b12167b8..8c4556408e 100755 --- a/t/t1005-read-tree-reset.sh +++ b/t/t1005-read-tree-reset.sh @@ -21,7 +21,7 @@ test_expect_success 'setup' ' git commit -m two ' -test_expect_failure 'reset should work' ' +test_expect_success 'reset should work' ' git read-tree -u --reset HEAD^ && git ls-files >actual && diff -u expect actual diff --git a/unpack-trees.c b/unpack-trees.c index cb8f847968..0cdf19817d 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -8,10 +8,18 @@ #include "progress.h" #include "refs.h" -static inline void remove_entry(int remove, struct unpack_trees_options *o) +static void add_entry(struct unpack_trees_options *o, struct cache_entry *ce, + unsigned int set, unsigned int clear) { - if (remove >= 0) - remove_index_entry_at(o->index, remove); + unsigned int size = ce_size(ce); + struct cache_entry *new = xmalloc(size); + + clear |= CE_HASHED | CE_UNHASHED; + + memcpy(new, ce, size); + new->next = NULL; + new->ce_flags = (new->ce_flags & ~clear) | set; + add_index_entry(&o->result, new, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE|ADD_CACHE_SKIP_DFCHECK); } /* Unlink the last component and attempt to remove leading @@ -51,11 +59,12 @@ static void check_updates(struct unpack_trees_options *o) unsigned cnt = 0, total = 0; struct progress *progress = NULL; char last_symlink[PATH_MAX]; + struct index_state *index = &o->result; int i; if (o->update && o->verbose_update) { - for (total = cnt = 0; cnt < o->index->cache_nr; cnt++) { - struct cache_entry *ce = o->index->cache[cnt]; + for (total = cnt = 0; cnt < index->cache_nr; cnt++) { + struct cache_entry *ce = index->cache[cnt]; if (ce->ce_flags & (CE_UPDATE | CE_REMOVE)) total++; } @@ -66,15 +75,15 @@ static void check_updates(struct unpack_trees_options *o) } *last_symlink = '\0'; - for (i = 0; i < o->index->cache_nr; i++) { - struct cache_entry *ce = o->index->cache[i]; + for (i = 0; i < index->cache_nr; i++) { + struct cache_entry *ce = index->cache[i]; if (ce->ce_flags & (CE_UPDATE | CE_REMOVE)) display_progress(progress, ++cnt); if (ce->ce_flags & CE_REMOVE) { if (o->update) unlink_entry(ce->name, last_symlink); - remove_index_entry_at(o->index, i); + remove_index_entry_at(&o->result, i); i--; continue; } @@ -89,28 +98,27 @@ static void check_updates(struct unpack_trees_options *o) stop_progress(&progress); } -static inline int call_unpack_fn(struct cache_entry **src, struct unpack_trees_options *o, int remove) +static inline int call_unpack_fn(struct cache_entry **src, struct unpack_trees_options *o) { - int ret = o->fn(src, o, remove); - if (ret > 0) { - o->pos += ret; + int ret = o->fn(src, o); + if (ret > 0) ret = 0; - } return ret; } static int unpack_index_entry(struct cache_entry *ce, struct unpack_trees_options *o) { struct cache_entry *src[5] = { ce, }; + + o->pos++; if (ce_stage(ce)) { if (o->skip_unmerged) { - o->pos++; - } else { - remove_entry(o->pos, o); + add_entry(o, ce, 0, 0); + return 0; } return 0; } - return call_unpack_fn(src, o, o->pos); + return call_unpack_fn(src, o); } int traverse_trees_recursive(int n, unsigned long dirmask, unsigned long df_conflicts, struct name_entry *names, struct traverse_info *info) @@ -200,7 +208,7 @@ static struct cache_entry *create_ce_entry(const struct traverse_info *info, con } static int unpack_nondirectories(int n, unsigned long mask, unsigned long dirmask, struct cache_entry *src[5], - const struct name_entry *names, const struct traverse_info *info, int remove) + const struct name_entry *names, const struct traverse_info *info) { int i; struct unpack_trees_options *o = info->data; @@ -240,12 +248,11 @@ static int unpack_nondirectories(int n, unsigned long mask, unsigned long dirmas } if (o->merge) - return call_unpack_fn(src, o, remove); + return call_unpack_fn(src, o); n += o->merge; - remove_entry(remove, o); for (i = 0; i < n; i++) - add_index_entry(o->index, src[i], ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK); + add_entry(o, src[i], 0, 0); return 0; } @@ -253,7 +260,6 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str { struct cache_entry *src[5] = { NULL, }; struct unpack_trees_options *o = info->data; - int remove = -1; const struct name_entry *p = names; /* Find first entry with a real name (we could use "mask" too) */ @@ -262,8 +268,8 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str /* Are we supposed to look at the index too? */ if (o->merge) { - while (o->pos < o->index->cache_nr) { - struct cache_entry *ce = o->index->cache[o->pos]; + while (o->pos < o->src_index->cache_nr) { + struct cache_entry *ce = o->src_index->cache[o->pos]; int cmp = compare_entry(ce, info, p); if (cmp < 0) { if (unpack_index_entry(ce, o) < 0) @@ -271,24 +277,25 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str continue; } if (!cmp) { + o->pos++; if (ce_stage(ce)) { /* * If we skip unmerged index entries, we'll skip this * entry *and* the tree entries associated with it! */ - if (o->skip_unmerged) + if (o->skip_unmerged) { + add_entry(o, ce, 0, 0); return mask; - remove_entry(o->pos, o); + } continue; } src[0] = ce; - remove = o->pos; } break; } } - if (unpack_nondirectories(n, mask, dirmask, src, names, info, remove) < 0) + if (unpack_nondirectories(n, mask, dirmask, src, names, info) < 0) return -1; /* Now handle any directories.. */ @@ -313,8 +320,6 @@ static int unpack_failed(struct unpack_trees_options *o, const char *message) return error(message); return -1; } - discard_index(o->index); - read_index(o->index); return -1; } @@ -330,6 +335,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options state.quiet = 1; state.refresh_cache = 1; + memset(&o->result, 0, sizeof(o->result)); o->merge_size = len; if (!dfc) @@ -350,8 +356,8 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options /* Any left-over entries in the index? */ if (o->merge) { - while (o->pos < o->index->cache_nr) { - struct cache_entry *ce = o->index->cache[o->pos]; + while (o->pos < o->src_index->cache_nr) { + struct cache_entry *ce = o->src_index->cache[o->pos]; if (unpack_index_entry(ce, o) < 0) return unpack_failed(o, NULL); } @@ -360,7 +366,10 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options if (o->trivial_merges_only && o->nontrivial_merge) return unpack_failed(o, "Merge requires file-level merging"); + o->src_index = NULL; check_updates(o); + if (o->dst_index) + *o->dst_index = o->result; return 0; } @@ -396,7 +405,7 @@ static int verify_uptodate(struct cache_entry *ce, return 0; if (!lstat(ce->name, &st)) { - unsigned changed = ie_match_stat(o->index, ce, &st, CE_MATCH_IGNORE_VALID); + unsigned changed = ie_match_stat(o->src_index, ce, &st, CE_MATCH_IGNORE_VALID); if (!changed) return 0; /* @@ -419,7 +428,7 @@ static int verify_uptodate(struct cache_entry *ce, static void invalidate_ce_path(struct cache_entry *ce, struct unpack_trees_options *o) { if (ce) - cache_tree_invalidate_path(o->index->cache_tree, ce->name); + cache_tree_invalidate_path(o->src_index->cache_tree, ce->name); } /* @@ -464,12 +473,12 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action, * in that directory. */ namelen = strlen(ce->name); - pos = index_name_pos(o->index, ce->name, namelen); + pos = index_name_pos(o->src_index, ce->name, namelen); if (0 <= pos) return cnt; /* we have it as nondirectory */ pos = -pos - 1; - for (i = pos; i < o->index->cache_nr; i++) { - struct cache_entry *ce = o->index->cache[i]; + for (i = pos; i < o->src_index->cache_nr; i++) { + struct cache_entry *ce = o->src_index->cache[i]; int len = ce_namelen(ce); if (len < namelen || strncmp(ce->name, ce->name, namelen) || @@ -481,7 +490,7 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action, if (!ce_stage(ce)) { if (verify_uptodate(ce, o)) return -1; - ce->ce_flags |= CE_REMOVE; + add_entry(o, ce, CE_REMOVE, 0); } cnt++; } @@ -567,9 +576,9 @@ static int verify_absent(struct cache_entry *ce, const char *action, * delete this path, which is in a subdirectory that * is being replaced with a blob. */ - cnt = index_name_pos(o->index, ce->name, strlen(ce->name)); + cnt = index_name_pos(&o->result, ce->name, strlen(ce->name)); if (0 <= cnt) { - struct cache_entry *ce = o->index->cache[cnt]; + struct cache_entry *ce = o->result.cache[cnt]; if (ce->ce_flags & CE_REMOVE) return 0; } @@ -584,7 +593,6 @@ static int verify_absent(struct cache_entry *ce, const char *action, static int merged_entry(struct cache_entry *merge, struct cache_entry *old, struct unpack_trees_options *o) { - merge->ce_flags |= CE_UPDATE; if (old) { /* * See if we can re-use the old CE directly? @@ -607,29 +615,29 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old, invalidate_ce_path(merge, o); } - merge->ce_flags &= ~CE_STAGEMASK; - add_index_entry(o->index, merge, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); + add_entry(o, merge, CE_UPDATE, CE_STAGEMASK); return 1; } static int deleted_entry(struct cache_entry *ce, struct cache_entry *old, struct unpack_trees_options *o) { - if (old) { - if (verify_uptodate(old, o)) - return -1; - } else + /* Did it exist in the index? */ + if (!old) { if (verify_absent(ce, "removed", o)) return -1; - ce->ce_flags |= CE_REMOVE; - add_index_entry(o->index, ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); + return 0; + } + if (verify_uptodate(old, o)) + return -1; + add_entry(o, ce, CE_REMOVE, 0); invalidate_ce_path(ce, o); return 1; } static int keep_entry(struct cache_entry *ce, struct unpack_trees_options *o) { - add_index_entry(o->index, ce, ADD_CACHE_OK_TO_ADD); + add_entry(o, ce, 0, 0); return 1; } @@ -649,9 +657,7 @@ static void show_stage_entry(FILE *o, } #endif -int threeway_merge(struct cache_entry **stages, - struct unpack_trees_options *o, - int remove) +int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o) { struct cache_entry *index; struct cache_entry *head; @@ -728,10 +734,8 @@ int threeway_merge(struct cache_entry **stages, } /* #1 */ - if (!head && !remote && any_anc_missing) { - remove_entry(remove, o); + if (!head && !remote && any_anc_missing) return 0; - } /* Under the new "aggressive" rule, we resolve mostly trivial * cases that we historically had git-merge-one-file resolve. @@ -763,10 +767,9 @@ int threeway_merge(struct cache_entry **stages, if ((head_deleted && remote_deleted) || (head_deleted && remote && remote_match) || (remote_deleted && head && head_match)) { - remove_entry(remove, o); if (index) return deleted_entry(index, index, o); - else if (ce && !head_deleted) { + if (ce && !head_deleted) { if (verify_absent(ce, "removed", o)) return -1; } @@ -789,7 +792,6 @@ int threeway_merge(struct cache_entry **stages, return -1; } - remove_entry(remove, o); o->nontrivial_merge = 1; /* #2, #3, #4, #6, #7, #9, #10, #11. */ @@ -824,9 +826,7 @@ int threeway_merge(struct cache_entry **stages, * "carry forward" rule, please see . * */ -int twoway_merge(struct cache_entry **src, - struct unpack_trees_options *o, - int remove) +int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o) { struct cache_entry *current = src[0]; struct cache_entry *oldtree = src[1]; @@ -854,7 +854,6 @@ int twoway_merge(struct cache_entry **src, } else if (oldtree && !newtree && same(current, oldtree)) { /* 10 or 11 */ - remove_entry(remove, o); return deleted_entry(oldtree, current, o); } else if (oldtree && newtree && @@ -864,7 +863,6 @@ int twoway_merge(struct cache_entry **src, } else { /* all other failures */ - remove_entry(remove, o); if (oldtree) return o->gently ? -1 : reject_merge(oldtree); if (current) @@ -876,7 +874,6 @@ int twoway_merge(struct cache_entry **src, } else if (newtree) return merged_entry(newtree, current, o); - remove_entry(remove, o); return deleted_entry(oldtree, current, o); } @@ -887,8 +884,7 @@ int twoway_merge(struct cache_entry **src, * stage0 does not have anything there. */ int bind_merge(struct cache_entry **src, - struct unpack_trees_options *o, - int remove) + struct unpack_trees_options *o) { struct cache_entry *old = src[0]; struct cache_entry *a = src[1]; @@ -898,7 +894,7 @@ int bind_merge(struct cache_entry **src, o->merge_size); if (a && old) return o->gently ? -1 : - error("Entry '%s' overlaps. Cannot bind.", a->name); + error("Entry '%s' overlaps with '%s'. Cannot bind.", a->name, old->name); if (!a) return keep_entry(old, o); else @@ -911,9 +907,7 @@ int bind_merge(struct cache_entry **src, * The rule is: * - take the stat information from stage0, take the data from stage1 */ -int oneway_merge(struct cache_entry **src, - struct unpack_trees_options *o, - int remove) +int oneway_merge(struct cache_entry **src, struct unpack_trees_options *o) { struct cache_entry *old = src[0]; struct cache_entry *a = src[1]; @@ -922,18 +916,19 @@ int oneway_merge(struct cache_entry **src, return error("Cannot do a oneway merge of %d trees", o->merge_size); - if (!a) { - remove_entry(remove, o); + if (!a) return deleted_entry(old, old, o); - } + if (old && same(old, a)) { + int update = 0; if (o->reset) { struct stat st; if (lstat(old->name, &st) || - ie_match_stat(o->index, old, &st, CE_MATCH_IGNORE_VALID)) - old->ce_flags |= CE_UPDATE; + ie_match_stat(o->src_index, old, &st, CE_MATCH_IGNORE_VALID)) + update |= CE_UPDATE; } - return keep_entry(old, o); + add_entry(o, old, update, 0); + return 0; } return merged_entry(a, old, o); } diff --git a/unpack-trees.h b/unpack-trees.h index 65add1652f..e8abbcd037 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -4,8 +4,7 @@ struct unpack_trees_options; typedef int (*merge_fn_t)(struct cache_entry **src, - struct unpack_trees_options *options, - int remove); + struct unpack_trees_options *options); struct unpack_trees_options { int reset; @@ -28,15 +27,18 @@ struct unpack_trees_options { struct cache_entry *df_conflict_entry; void *unpack_data; - struct index_state *index; + + struct index_state *dst_index; + const struct index_state *src_index; + struct index_state result; }; extern int unpack_trees(unsigned n, struct tree_desc *t, struct unpack_trees_options *options); -int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o, int); -int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o, int); -int bind_merge(struct cache_entry **src, struct unpack_trees_options *o, int); -int oneway_merge(struct cache_entry **src, struct unpack_trees_options *o, int); +int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o); +int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o); +int bind_merge(struct cache_entry **src, struct unpack_trees_options *o); +int oneway_merge(struct cache_entry **src, struct unpack_trees_options *o); #endif -- cgit v1.3 From 20a16eb33eee99fd3eab00c72f012b98d4eeee76 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 10 Mar 2008 23:51:13 -0700 Subject: unpack_trees(): fix diff-index regression. When skip_unmerged option is not given, unpack_trees() should not just skip unmerged cache entries but keep them in the result for the caller to sort them out. For callers other than diff-index, the incoming index should never be unmerged, but diff-index is a special case caller. Signed-off-by: Junio C Hamano --- diff-lib.c | 18 ++++++++++++++++++ unpack-trees.c | 2 -- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index 9520773f3b..52dbac34a4 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -641,6 +641,21 @@ static void do_oneway_diff(struct unpack_trees_options *o, show_modified(revs, tree, idx, 1, cached, match_missing); } +static inline void skip_same_name(struct cache_entry *ce, struct unpack_trees_options *o) +{ + int len = ce_namelen(ce); + const struct index_state *index = o->src_index; + + while (o->pos < index->cache_nr) { + struct cache_entry *next = index->cache[o->pos]; + if (len != ce_namelen(next)) + break; + if (memcmp(ce->name, next->name, len)) + break; + o->pos++; + } +} + /* * The unpack_trees() interface is designed for merging, so * the different source entries are designed primarily for @@ -662,6 +677,9 @@ static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o) struct cache_entry *tree = src[1]; struct rev_info *revs = o->unpack_data; + if (idx && ce_stage(idx)) + skip_same_name(idx, o); + /* * Unpack-trees generates a DF/conflict entry if * there was a directory in the index and a tree diff --git a/unpack-trees.c b/unpack-trees.c index 5a0f0382b8..be89d52e8c 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -116,7 +116,6 @@ static int unpack_index_entry(struct cache_entry *ce, struct unpack_trees_option add_entry(o, ce, 0, 0); return 0; } - return 0; } return call_unpack_fn(src, o); } @@ -286,7 +285,6 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str add_entry(o, ce, 0, 0); return mask; } - continue; } src[0] = ce; } -- cgit v1.3 From 948dd346fd6748f8c2c0ae488759cbbd05a09320 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 30 Mar 2008 17:29:48 -0700 Subject: diff-index: careful when inspecting work tree items Earlier, if you changed a staged path into a directory in the work tree, we happily ran lstat(2) on it and found that it exists, and declared that the user changed it to a gitlink. This is wrong for two reasons: (1) It may be a directory, but it may not be a submodule, and in the latter case, the change we need to report is "the blob at the path has disappeared". We need to check with resolve_gitlink_ref() to be consistent with what "git add" and "git update-index --add" does. (2) lstat(2) may have succeeded only because a leading component of the path was turned into a symbolic link that points at something that exists in the work tree. In such a case, the path itself does not exist anymore, as far as the index is concerned. This fixes these breakages in diff-index that the previous patch has exposed. Signed-off-by: Junio C Hamano --- diff-lib.c | 69 ++++++++++++++++++++++++++++++++-------- t/t2201-add-update-typechange.sh | 2 +- 2 files changed, 56 insertions(+), 15 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index 52dbac34a4..ad9ed13fc9 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -10,6 +10,7 @@ #include "cache-tree.h" #include "path-list.h" #include "unpack-trees.h" +#include "refs.h" /* * diff-files @@ -333,6 +334,26 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) } return run_diff_files(revs, options); } +/* + * See if work tree has an entity that can be staged. Return 0 if so, + * return 1 if not and return -1 if error. + */ +static int check_work_tree_entity(const struct cache_entry *ce, struct stat *st, char *symcache) +{ + if (lstat(ce->name, st) < 0) { + if (errno != ENOENT && errno != ENOTDIR) + return -1; + return 1; + } + if (has_symlink_leading_path(ce->name, symcache)) + return 1; + if (S_ISDIR(st->st_mode)) { + unsigned char sub[20]; + if (resolve_gitlink_ref(ce->name, "HEAD", sub)) + return 1; + } + return 0; +} int run_diff_files(struct rev_info *revs, unsigned int option) { @@ -468,6 +489,11 @@ int run_diff_files(struct rev_info *revs, unsigned int option) * diff-index */ +struct oneway_unpack_data { + struct rev_info *revs; + char symcache[PATH_MAX]; +}; + /* A file entry went away or appeared */ static void diff_index_show_file(struct rev_info *revs, const char *prefix, @@ -481,7 +507,8 @@ static void diff_index_show_file(struct rev_info *revs, static int get_stat_data(struct cache_entry *ce, const unsigned char **sha1p, unsigned int *modep, - int cached, int match_missing) + int cached, int match_missing, + struct oneway_unpack_data *cbdata) { const unsigned char *sha1 = ce->sha1; unsigned int mode = ce->ce_mode; @@ -489,8 +516,11 @@ static int get_stat_data(struct cache_entry *ce, if (!cached) { int changed; struct stat st; - if (lstat(ce->name, &st) < 0) { - if (errno == ENOENT && match_missing) { + changed = check_work_tree_entity(ce, &st, cbdata->symcache); + if (changed < 0) + return -1; + else if (changed) { + if (match_missing) { *sha1p = sha1; *modep = mode; return 0; @@ -509,23 +539,25 @@ static int get_stat_data(struct cache_entry *ce, return 0; } -static void show_new_file(struct rev_info *revs, +static void show_new_file(struct oneway_unpack_data *cbdata, struct cache_entry *new, int cached, int match_missing) { const unsigned char *sha1; unsigned int mode; + struct rev_info *revs = cbdata->revs; - /* New file in the index: it might actually be different in + /* + * New file in the index: it might actually be different in * the working copy. */ - if (get_stat_data(new, &sha1, &mode, cached, match_missing) < 0) + if (get_stat_data(new, &sha1, &mode, cached, match_missing, cbdata) < 0) return; diff_index_show_file(revs, "+", new, sha1, mode); } -static int show_modified(struct rev_info *revs, +static int show_modified(struct oneway_unpack_data *cbdata, struct cache_entry *old, struct cache_entry *new, int report_missing, @@ -533,8 +565,9 @@ static int show_modified(struct rev_info *revs, { unsigned int mode, oldmode; const unsigned char *sha1; + struct rev_info *revs = cbdata->revs; - if (get_stat_data(new, &sha1, &mode, cached, match_missing) < 0) { + if (get_stat_data(new, &sha1, &mode, cached, match_missing, cbdata) < 0) { if (report_missing) diff_index_show_file(revs, "-", old, old->sha1, old->ce_mode); @@ -602,7 +635,8 @@ static void do_oneway_diff(struct unpack_trees_options *o, struct cache_entry *idx, struct cache_entry *tree) { - struct rev_info *revs = o->unpack_data; + struct oneway_unpack_data *cbdata = o->unpack_data; + struct rev_info *revs = cbdata->revs; int match_missing, cached; /* @@ -625,7 +659,7 @@ static void do_oneway_diff(struct unpack_trees_options *o, * Something added to the tree? */ if (!tree) { - show_new_file(revs, idx, cached, match_missing); + show_new_file(cbdata, idx, cached, match_missing); return; } @@ -638,7 +672,7 @@ static void do_oneway_diff(struct unpack_trees_options *o, } /* Show difference between old and new */ - show_modified(revs, tree, idx, 1, cached, match_missing); + show_modified(cbdata, tree, idx, 1, cached, match_missing); } static inline void skip_same_name(struct cache_entry *ce, struct unpack_trees_options *o) @@ -675,7 +709,8 @@ static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o) { struct cache_entry *idx = src[0]; struct cache_entry *tree = src[1]; - struct rev_info *revs = o->unpack_data; + struct oneway_unpack_data *cbdata = o->unpack_data; + struct rev_info *revs = cbdata->revs; if (idx && ce_stage(idx)) skip_same_name(idx, o); @@ -702,6 +737,7 @@ int run_diff_index(struct rev_info *revs, int cached) const char *tree_name; struct unpack_trees_options opts; struct tree_desc t; + struct oneway_unpack_data unpack_cb; mark_merge_entries(); @@ -711,12 +747,14 @@ int run_diff_index(struct rev_info *revs, int cached) if (!tree) return error("bad tree object %s", tree_name); + unpack_cb.revs = revs; + unpack_cb.symcache[0] = '\0'; memset(&opts, 0, sizeof(opts)); opts.head_idx = 1; opts.index_only = cached; opts.merge = 1; opts.fn = oneway_diff; - opts.unpack_data = revs; + opts.unpack_data = &unpack_cb; opts.src_index = &the_index; opts.dst_index = NULL; @@ -738,6 +776,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) struct cache_entry *last = NULL; struct unpack_trees_options opts; struct tree_desc t; + struct oneway_unpack_data unpack_cb; /* * This is used by git-blame to run diff-cache internally; @@ -766,12 +805,14 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) if (!tree) die("bad tree object %s", sha1_to_hex(tree_sha1)); + unpack_cb.revs = &revs; + unpack_cb.symcache[0] = '\0'; memset(&opts, 0, sizeof(opts)); opts.head_idx = 1; opts.index_only = 1; opts.merge = 1; opts.fn = oneway_diff; - opts.unpack_data = &revs; + opts.unpack_data = &unpack_cb; opts.src_index = &the_index; opts.dst_index = &the_index; diff --git a/t/t2201-add-update-typechange.sh b/t/t2201-add-update-typechange.sh index 75c440c74b..469a8e0739 100755 --- a/t/t2201-add-update-typechange.sh +++ b/t/t2201-add-update-typechange.sh @@ -109,7 +109,7 @@ test_expect_failure diff-files ' diff -u expect-files actual ' -test_expect_failure diff-index ' +test_expect_success diff-index ' git diff-index --raw HEAD -- >actual && diff -u expect-index actual ' -- cgit v1.3 From f58dbf23c33e0e79622f4344b48ab5bc9bc360cc Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 30 Mar 2008 17:30:08 -0700 Subject: diff-files: careful when inspecting work tree items This fixes the same breakage in diff-files. Signed-off-by: Junio C Hamano --- diff-lib.c | 17 +++++++++++------ t/t2201-add-update-typechange.sh | 6 +++--- 2 files changed, 14 insertions(+), 9 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index ad9ed13fc9..069e4507ae 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -362,10 +362,12 @@ int run_diff_files(struct rev_info *revs, unsigned int option) int silent_on_removed = option & DIFF_SILENT_ON_REMOVED; unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED) ? CE_MATCH_RACY_IS_DIRTY : 0); + char symcache[PATH_MAX]; if (diff_unmerged_stage < 0) diff_unmerged_stage = 2; entries = active_nr; + symcache[0] = '\0'; for (i = 0; i < entries; i++) { struct stat st; unsigned int oldmode, newmode; @@ -397,16 +399,17 @@ int run_diff_files(struct rev_info *revs, unsigned int option) memset(&(dpath->parent[0]), 0, sizeof(struct combine_diff_parent)*5); - if (lstat(ce->name, &st) < 0) { - if (errno != ENOENT && errno != ENOTDIR) { + changed = check_work_tree_entity(ce, &st, symcache); + if (!changed) + dpath->mode = ce_mode_from_stat(ce, st.st_mode); + else { + if (changed < 0) { perror(ce->name); continue; } if (silent_on_removed) continue; } - else - dpath->mode = ce_mode_from_stat(ce, st.st_mode); while (i < entries) { struct cache_entry *nce = active_cache[i]; @@ -459,8 +462,10 @@ int run_diff_files(struct rev_info *revs, unsigned int option) if (ce_uptodate(ce)) continue; - if (lstat(ce->name, &st) < 0) { - if (errno != ENOENT && errno != ENOTDIR) { + + changed = check_work_tree_entity(ce, &st, symcache); + if (changed) { + if (changed < 0) { perror(ce->name); continue; } diff --git a/t/t2201-add-update-typechange.sh b/t/t2201-add-update-typechange.sh index 469a8e0739..e15e3eb81b 100755 --- a/t/t2201-add-update-typechange.sh +++ b/t/t2201-add-update-typechange.sh @@ -104,7 +104,7 @@ test_expect_success modify ' } >expect-final ' -test_expect_failure diff-files ' +test_expect_success diff-files ' git diff-files --raw >actual && diff -u expect-files actual ' @@ -114,7 +114,7 @@ test_expect_success diff-index ' diff -u expect-index actual ' -test_expect_failure 'add -u' ' +test_expect_success 'add -u' ' rm -f ".git/saved-index" && cp -p ".git/index" ".git/saved-index" && git add -u && @@ -122,7 +122,7 @@ test_expect_failure 'add -u' ' diff -u expect-final actual ' -test_expect_failure 'commit -a' ' +test_expect_success 'commit -a' ' if test -f ".git/saved-index" then rm -f ".git/index" && -- cgit v1.3 From 8fa29602d4cf8c9ec7d837f7308a9582a8372cb5 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 30 Mar 2008 12:39:25 -0700 Subject: diff-files: mark an index entry we know is up-to-date as such This does not make any difference when running diff-files alone, but if you internally run run_diff_files() and then run other operations further on the index, we do not have to run lstat(2) again on entries we already have checked. Signed-off-by: Junio C Hamano --- diff-lib.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index 069e4507ae..6e7ab29e34 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -476,8 +476,11 @@ int run_diff_files(struct rev_info *revs, unsigned int option) continue; } changed = ce_match_stat(ce, &st, ce_option); - if (!changed && !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)) - continue; + if (!changed) { + ce_mark_uptodate(ce); + if (!DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)) + continue; + } oldmode = ce->ce_mode; newmode = ce_mode_from_stat(ce, st.st_mode); diff_change(&revs->diffopt, oldmode, newmode, -- cgit v1.3 From 59b0c24daaac3c2203dd8ac2de4dfcad909481a5 Mon Sep 17 00:00:00 2001 From: Matthieu Moy Date: Thu, 24 Apr 2008 20:06:36 +0200 Subject: git-svn: detect and fail gracefully when dcommitting to a void The command git svn clone (URL of an empty SVN repo here) works, creates an empty git repository. I can perform the initial commit there, but then, "git svn dcommit" says : Use of uninitialized value in concatenation (.) or string at .../git-svn line 414. Committing to ... Unable to determine upstream SVN information from HEAD history I guess a correct management of the initial commit in git-svn would be hard to implement, but at least, the error message can be improved. First step is something like the patch below, and better would be for "git svn clone" to warn that it won't be able to do much with the cloned repo. Acked-by: Eric Wong Signed-off-by: Junio C Hamano --- diff-lib.c | 3 +++ git-svn.perl | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index 069e4507ae..cfd629da48 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -264,6 +264,9 @@ int setup_diff_no_index(struct rev_info *revs, DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); break; } + if (nongit && argc != i + 2) + die("git diff [--no-index] takes two paths"); + if (argc != i + 2 || (!is_outside_repo(argv[i + 1], nongit, prefix) && !is_outside_repo(argv[i], nongit, prefix))) return -1; diff --git a/git-svn.perl b/git-svn.perl index b1510495a7..711e7b7eb9 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -410,10 +410,12 @@ sub cmd_dcommit { $head ||= 'HEAD'; my @refs; my ($url, $rev, $uuid, $gs) = working_head_info($head, \@refs); - print "Committing to $url ...\n"; + if ($url) { + print "Committing to $url ...\n"; + } unless ($gs) { die "Unable to determine upstream SVN information from ", - "$head history\n"; + "$head history.\nPerhaps the repository is empty."; } my $last_rev; my ($linear_refs, $parents) = linearize_history($gs, \@refs); -- cgit v1.3 From 1392a377219adfee7cc7532e3c60e51d79ab40b1 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 3 May 2008 17:04:42 -0700 Subject: diff: a submodule not checked out is not modified 948dd34 (diff-index: careful when inspecting work tree items, 2008-03-30) made the work tree check careful not to be fooled by a new directory that exists at a place the index expects a blob. For such a change to be a typechange from blob to submodule, the new directory has to be a repository. However, if the index expects a submodule there, we should not insist the work tree entity to be a repository --- a simple directory that is not a full fledged repository (even an empty directory would do) should be considered an unmodified subproject, because that is how a superproject with a submodule is checked out sparsely by default. This makes the function check_work_tree_entity() even more careful not to report a submodule that is not checked out as removed. It fixes the recently added test in t4027. Signed-off-by: Junio C Hamano --- diff-lib.c | 25 ++++++++++++++++++++++--- t/t4027-diff-submodule.sh | 2 +- 2 files changed, 23 insertions(+), 4 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index cfd629da48..e0ebcdcf54 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -337,9 +337,15 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) } return run_diff_files(revs, options); } + /* - * See if work tree has an entity that can be staged. Return 0 if so, - * return 1 if not and return -1 if error. + * Has the work tree entity been removed? + * + * Return 1 if it was removed from the work tree, 0 if an entity to be + * compared with the cache entry ce still exists (the latter includes + * the case where a directory that is not a submodule repository + * exists for ce that is a submodule -- it is a submodule that is not + * checked out). Return negative for an error. */ static int check_work_tree_entity(const struct cache_entry *ce, struct stat *st, char *symcache) { @@ -352,7 +358,20 @@ static int check_work_tree_entity(const struct cache_entry *ce, struct stat *st, return 1; if (S_ISDIR(st->st_mode)) { unsigned char sub[20]; - if (resolve_gitlink_ref(ce->name, "HEAD", sub)) + + /* + * If ce is already a gitlink, we can have a plain + * directory (i.e. the submodule is not checked out), + * or a checked out submodule. Either case this is not + * a case where something was removed from the work tree, + * so we will return 0. + * + * Otherwise, if the directory is not a submodule + * repository, that means ce which was a blob turned into + * a directory --- the blob was removed! + */ + if (!S_ISGITLINK(ce->ce_mode) && + resolve_gitlink_ref(ce->name, "HEAD", sub)) return 1; } return 0; diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh index 61caad0f5d..ba6679c6e4 100755 --- a/t/t4027-diff-submodule.sh +++ b/t/t4027-diff-submodule.sh @@ -50,7 +50,7 @@ test_expect_success 'git diff-files --raw' ' test_cmp expect actual.files ' -test_expect_failure 'git diff (empty submodule dir)' ' +test_expect_success 'git diff (empty submodule dir)' ' : >empty && rm -rf sub/* sub/.git && git diff > actual.empty && -- cgit v1.3 From 451244d724f921eca9ffaf526d45c825f7c6f4eb Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 3 May 2008 17:23:46 -0700 Subject: diff-lib.c: rename check_work_tree_entity() The function is about checking for removed work tree item, so name it accordingly to avoid future confusion. Signed-off-by: Junio C Hamano --- diff-lib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index e0ebcdcf54..4a3e25536c 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -347,7 +347,7 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) * exists for ce that is a submodule -- it is a submodule that is not * checked out). Return negative for an error. */ -static int check_work_tree_entity(const struct cache_entry *ce, struct stat *st, char *symcache) +static int check_removed(const struct cache_entry *ce, struct stat *st, char *symcache) { if (lstat(ce->name, st) < 0) { if (errno != ENOENT && errno != ENOTDIR) @@ -421,7 +421,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) memset(&(dpath->parent[0]), 0, sizeof(struct combine_diff_parent)*5); - changed = check_work_tree_entity(ce, &st, symcache); + changed = check_removed(ce, &st, symcache); if (!changed) dpath->mode = ce_mode_from_stat(ce, st.st_mode); else { @@ -485,7 +485,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) if (ce_uptodate(ce)) continue; - changed = check_work_tree_entity(ce, &st, symcache); + changed = check_removed(ce, &st, symcache); if (changed) { if (changed < 0) { perror(ce->name); @@ -543,7 +543,7 @@ static int get_stat_data(struct cache_entry *ce, if (!cached) { int changed; struct stat st; - changed = check_work_tree_entity(ce, &st, cbdata->symcache); + changed = check_removed(ce, &st, cbdata->symcache); if (changed < 0) return -1; else if (changed) { -- cgit v1.3 From c40641b77b0274186fd1b327d5dc3246f814aaaf Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 9 May 2008 09:21:07 -0700 Subject: Optimize symlink/directory detection This is the base for making symlink detection in the middle fo a pathname saner and (much) more efficient. Under various loads, we want to verify that the full path leading up to a filename is a real directory tree, and that when we successfully do an 'lstat()' on a filename, we don't get a false positive due to a symlink in the middle of the path that git should have seen as a symlink, not as a normal path component. The 'has_symlink_leading_path()' function already did this, and cached a single level of symlink information, but didn't cache the _lack_ of a symlink, so the normal behaviour was actually the wrong way around, and we ended up doing an 'lstat()' on each path component to check that it was a real directory. This caches the last detected full directory and symlink entries, and speeds up especially deep directory structures a lot by avoiding to lstat() all the directories leading up to each entry in the index. [ This can - and should - probably be extended upon so that we eventually never do a bare 'lstat()' on any path entries at *all* when checking the index, but always check the full path carefully. Right now we do not generally check the whole path for all our normal quick index revalidation. We should also make sure that we're careful about all the invalidation, ie when we remove a link and replace it by a directory we should invalidate the symlink cache if it matches (and vice versa for the directory cache). But regardless, the basic function needs to be sane to do that. The old 'has_symlink_leading_path()' was not capable enough - or indeed the code readable enough - to really do that sanely. So I'm pushing this as not just an optimization, but as a base for further work. ] Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- builtin-apply.c | 2 +- cache.h | 2 +- diff-lib.c | 10 +++---- symlinks.c | 82 ++++++++++++++++++++++++++++++++++----------------------- unpack-trees.c | 12 ++++----- 5 files changed, 61 insertions(+), 47 deletions(-) (limited to 'diff-lib.c') diff --git a/builtin-apply.c b/builtin-apply.c index caa3f2aa0c..1103625a4a 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -2247,7 +2247,7 @@ static int check_to_create_blob(const char *new_name, int ok_if_exists) * In such a case, path "new_name" does not exist as * far as git is concerned. */ - if (has_symlink_leading_path(new_name, NULL)) + if (has_symlink_leading_path(strlen(new_name), new_name)) return 0; return error("%s: already exists in working directory", new_name); diff --git a/cache.h b/cache.h index 4803b032ec..0d9d9e2577 100644 --- a/cache.h +++ b/cache.h @@ -598,7 +598,7 @@ struct checkout { }; extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath); -extern int has_symlink_leading_path(const char *name, char *last_symlink); +extern int has_symlink_leading_path(int len, const char *name); extern struct alternate_object_database { struct alternate_object_database *next; diff --git a/diff-lib.c b/diff-lib.c index c5894c7c5a..fe2ccec7e6 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -347,14 +347,14 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) * exists for ce that is a submodule -- it is a submodule that is not * checked out). Return negative for an error. */ -static int check_removed(const struct cache_entry *ce, struct stat *st, char *symcache) +static int check_removed(const struct cache_entry *ce, struct stat *st) { if (lstat(ce->name, st) < 0) { if (errno != ENOENT && errno != ENOTDIR) return -1; return 1; } - if (has_symlink_leading_path(ce->name, symcache)) + if (has_symlink_leading_path(ce_namelen(ce), ce->name)) return 1; if (S_ISDIR(st->st_mode)) { unsigned char sub[20]; @@ -421,7 +421,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) memset(&(dpath->parent[0]), 0, sizeof(struct combine_diff_parent)*5); - changed = check_removed(ce, &st, symcache); + changed = check_removed(ce, &st); if (!changed) dpath->mode = ce_mode_from_stat(ce, st.st_mode); else { @@ -485,7 +485,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) if (ce_uptodate(ce)) continue; - changed = check_removed(ce, &st, symcache); + changed = check_removed(ce, &st); if (changed) { if (changed < 0) { perror(ce->name); @@ -546,7 +546,7 @@ static int get_stat_data(struct cache_entry *ce, if (!cached) { int changed; struct stat st; - changed = check_removed(ce, &st, cbdata->symcache); + changed = check_removed(ce, &st); if (changed < 0) return -1; else if (changed) { diff --git a/symlinks.c b/symlinks.c index be9ace6c04..5a5e781a15 100644 --- a/symlinks.c +++ b/symlinks.c @@ -1,48 +1,64 @@ #include "cache.h" -int has_symlink_leading_path(const char *name, char *last_symlink) -{ +struct pathname { + int len; char path[PATH_MAX]; - const char *sp, *ep; - char *dp; - - sp = name; - dp = path; - - if (last_symlink && *last_symlink) { - size_t last_len = strlen(last_symlink); - size_t len = strlen(name); - if (last_len < len && - !strncmp(name, last_symlink, last_len) && - name[last_len] == '/') - return 1; - *last_symlink = '\0'; +}; + +/* Return matching pathname prefix length, or zero if not matching */ +static inline int match_pathname(int len, const char *name, struct pathname *match) +{ + int match_len = match->len; + return (len > match_len && + name[match_len] == '/' && + !memcmp(name, match->path, match_len)) ? match_len : 0; +} + +static inline void set_pathname(int len, const char *name, struct pathname *match) +{ + if (len < PATH_MAX) { + match->len = len; + memcpy(match->path, name, len); + match->path[len] = 0; } +} + +int has_symlink_leading_path(int len, const char *name) +{ + static struct pathname link, nonlink; + char path[PATH_MAX]; + struct stat st; + char *sp; + int known_dir; - while (1) { - size_t len; - struct stat st; + /* + * See if the last known symlink cache matches. + */ + if (match_pathname(len, name, &link)) + return 1; - ep = strchr(sp, '/'); - if (!ep) - break; - len = ep - sp; - if (PATH_MAX <= dp + len - path + 2) - return 0; /* new name is longer than that??? */ - memcpy(dp, sp, len); - dp[len] = 0; + /* + * Get rid of the last known directory part + */ + known_dir = match_pathname(len, name, &nonlink); + + while ((sp = strchr(name + known_dir + 1, '/')) != NULL) { + int thislen = sp - name ; + memcpy(path, name, thislen); + path[thislen] = 0; if (lstat(path, &st)) return 0; + if (S_ISDIR(st.st_mode)) { + set_pathname(thislen, path, &nonlink); + known_dir = thislen; + continue; + } if (S_ISLNK(st.st_mode)) { - if (last_symlink) - strcpy(last_symlink, path); + set_pathname(thislen, path, &link); return 1; } - - dp[len++] = '/'; - dp = dp + len; - sp = ep + 1; + break; } return 0; } diff --git a/unpack-trees.c b/unpack-trees.c index feae846226..1ab28fda45 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -26,11 +26,12 @@ static void add_entry(struct unpack_trees_options *o, struct cache_entry *ce, * directories, in case this unlink is the removal of the * last entry in the directory -- empty directories are removed. */ -static void unlink_entry(char *name, char *last_symlink) +static void unlink_entry(struct cache_entry *ce) { char *cp, *prev; + char *name = ce->name; - if (has_symlink_leading_path(name, last_symlink)) + if (has_symlink_leading_path(ce_namelen(ce), ce->name)) return; if (unlink(name)) return; @@ -58,7 +59,6 @@ static int check_updates(struct unpack_trees_options *o) { unsigned cnt = 0, total = 0; struct progress *progress = NULL; - char last_symlink[PATH_MAX]; struct index_state *index = &o->result; int i; int errs = 0; @@ -75,14 +75,13 @@ static int check_updates(struct unpack_trees_options *o) cnt = 0; } - *last_symlink = '\0'; for (i = 0; i < index->cache_nr; i++) { struct cache_entry *ce = index->cache[i]; if (ce->ce_flags & CE_REMOVE) { display_progress(progress, ++cnt); if (o->update) - unlink_entry(ce->name, last_symlink); + unlink_entry(ce); remove_index_entry_at(&o->result, i); i--; continue; @@ -97,7 +96,6 @@ static int check_updates(struct unpack_trees_options *o) ce->ce_flags &= ~CE_UPDATE; if (o->update) { errs |= checkout_entry(ce, &state, NULL); - *last_symlink = '\0'; } } } @@ -553,7 +551,7 @@ static int verify_absent(struct cache_entry *ce, const char *action, if (o->index_only || o->reset || !o->update) return 0; - if (has_symlink_leading_path(ce->name, NULL)) + if (has_symlink_leading_path(ce_namelen(ce), ce->name)) return 0; if (!lstat(ce->name, &st)) { -- cgit v1.3 From 0569e9b8cea20d5eedfec66730a9711a0907ab0d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 23 May 2008 22:28:56 -0700 Subject: "git diff": do not ignore index without --no-index Even if "foo" and/or "bar" does not exist in index, "git diff foo bar" should not change behaviour drastically from "git diff foo bar baz" or "git diff foo". A feature that "sometimes works and is handy" is an unreliable cute hack. "git diff foo bar" outside a git repository continues to work as a more colourful alternative to "diff -u" as before. Signed-off-by: Junio C Hamano --- Makefile | 1 + builtin-diff.c | 55 +++- diff-lib.c | 323 --------------------- diff-no-index.c | 231 +++++++++++++++ diff.h | 6 +- t/t4013-diff-various.sh | 1 + t/t4013/diff.diff_--name-status_dir2_dir | 1 - .../diff.diff_--no-index_--name-status_dir2_dir | 3 + 8 files changed, 283 insertions(+), 338 deletions(-) create mode 100644 diff-no-index.c create mode 100644 t/t4013/diff.diff_--no-index_--name-status_dir2_dir (limited to 'diff-lib.c') diff --git a/Makefile b/Makefile index 865e2bfcf1..ad09e6c8ba 100644 --- a/Makefile +++ b/Makefile @@ -405,6 +405,7 @@ LIB_OBJS += diffcore-order.o LIB_OBJS += diffcore-pickaxe.o LIB_OBJS += diffcore-rename.o LIB_OBJS += diff-delta.o +LIB_OBJS += diff-no-index.o LIB_OBJS += diff-lib.o LIB_OBJS += diff.o LIB_OBJS += dir.o diff --git a/builtin-diff.c b/builtin-diff.c index 7c2a8412fa..8b3b51eae0 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -202,6 +202,37 @@ static void refresh_index_quietly(void) rollback_lock_file(lock_file); } +static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv) +{ + int result; + unsigned int options = 0; + + while (1 < argc && argv[1][0] == '-') { + if (!strcmp(argv[1], "--base")) + revs->max_count = 1; + else if (!strcmp(argv[1], "--ours")) + revs->max_count = 2; + else if (!strcmp(argv[1], "--theirs")) + revs->max_count = 3; + else if (!strcmp(argv[1], "-q")) + options |= DIFF_SILENT_ON_REMOVED; + else + return error("invalid option: %s", argv[1]); + argv++; argc--; + } + + if (revs->max_count == -1 && + (revs->diffopt.output_format & DIFF_FORMAT_PATCH)) + revs->combine_merges = revs->dense_combined_merges = 1; + + if (read_cache() < 0) { + perror("read_cache"); + return -1; + } + result = run_diff_files(revs, options); + return diff_result_code(&revs->diffopt, result); +} + int cmd_diff(int argc, const char **argv, const char *prefix) { int i; @@ -230,6 +261,9 @@ int cmd_diff(int argc, const char **argv, const char *prefix) * N=2, M=0: * tree vs tree (diff-tree) * + * N=0, M=0, P=2: + * compare two filesystem entities (aka --no-index). + * * Other cases are errors. */ @@ -240,21 +274,21 @@ int cmd_diff(int argc, const char **argv, const char *prefix) diff_use_color_default = git_use_color_default; init_revisions(&rev, prefix); + + /* If this is a no-index diff, just run it and exit there. */ + diff_no_index(&rev, argc, argv, nongit, prefix); + + /* Otherwise, we are doing the usual "git" diff */ rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; - if (!setup_diff_no_index(&rev, argc, argv, nongit, prefix)) - argc = 0; - else - argc = setup_revisions(argc, argv, &rev, NULL); + if (nongit) + die("Not a git repository"); + 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"); } - if (rev.diffopt.prefix && nongit) { - rev.diffopt.prefix = NULL; - rev.diffopt.prefix_length = 0; - } DIFF_OPT_SET(&rev.diffopt, ALLOW_EXTERNAL); DIFF_OPT_SET(&rev.diffopt, RECURSIVE); @@ -265,7 +299,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix) if (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS)) setup_pager(); - /* Do we have --cached and not have a pending object, then + /* + * Do we have --cached and not have a pending object, then * default to HEAD by hand. Eek. */ if (!rev.pending.nr) { @@ -333,7 +368,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) if (!ents) { switch (blobs) { case 0: - result = run_diff_files_cmd(&rev, argc, argv); + result = builtin_diff_files(&rev, argc, argv); break; case 1: if (paths != 1) diff --git a/diff-lib.c b/diff-lib.c index fe2ccec7e6..b17722d66a 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -8,7 +8,6 @@ #include "diffcore.h" #include "revision.h" #include "cache-tree.h" -#include "path-list.h" #include "unpack-trees.h" #include "refs.h" @@ -16,328 +15,6 @@ * diff-files */ -static int read_directory(const char *path, struct path_list *list) -{ - DIR *dir; - struct dirent *e; - - if (!(dir = opendir(path))) - return error("Could not open directory %s", path); - - while ((e = readdir(dir))) - if (strcmp(".", e->d_name) && strcmp("..", e->d_name)) - path_list_insert(e->d_name, list); - - closedir(dir); - return 0; -} - -static int get_mode(const char *path, int *mode) -{ - struct stat st; - - if (!path || !strcmp(path, "/dev/null")) - *mode = 0; - else if (!strcmp(path, "-")) - *mode = create_ce_mode(0666); - else if (stat(path, &st)) - return error("Could not access '%s'", path); - else - *mode = st.st_mode; - return 0; -} - -static int queue_diff(struct diff_options *o, - const char *name1, const char *name2) -{ - int mode1 = 0, mode2 = 0; - - if (get_mode(name1, &mode1) || get_mode(name2, &mode2)) - return -1; - - if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2)) - return error("file/directory conflict: %s, %s", name1, name2); - - if (S_ISDIR(mode1) || S_ISDIR(mode2)) { - char buffer1[PATH_MAX], buffer2[PATH_MAX]; - struct path_list p1 = {NULL, 0, 0, 1}, p2 = {NULL, 0, 0, 1}; - int len1 = 0, len2 = 0, i1, i2, ret = 0; - - if (name1 && read_directory(name1, &p1)) - return -1; - if (name2 && read_directory(name2, &p2)) { - path_list_clear(&p1, 0); - return -1; - } - - if (name1) { - len1 = strlen(name1); - if (len1 > 0 && name1[len1 - 1] == '/') - len1--; - memcpy(buffer1, name1, len1); - buffer1[len1++] = '/'; - } - - if (name2) { - len2 = strlen(name2); - if (len2 > 0 && name2[len2 - 1] == '/') - len2--; - memcpy(buffer2, name2, len2); - buffer2[len2++] = '/'; - } - - for (i1 = i2 = 0; !ret && (i1 < p1.nr || i2 < p2.nr); ) { - const char *n1, *n2; - int comp; - - if (i1 == p1.nr) - comp = 1; - else if (i2 == p2.nr) - comp = -1; - else - comp = strcmp(p1.items[i1].path, - p2.items[i2].path); - - if (comp > 0) - n1 = NULL; - else { - n1 = buffer1; - strncpy(buffer1 + len1, p1.items[i1++].path, - PATH_MAX - len1); - } - - if (comp < 0) - n2 = NULL; - else { - n2 = buffer2; - strncpy(buffer2 + len2, p2.items[i2++].path, - PATH_MAX - len2); - } - - ret = queue_diff(o, n1, n2); - } - path_list_clear(&p1, 0); - path_list_clear(&p2, 0); - - return ret; - } else { - struct diff_filespec *d1, *d2; - - if (DIFF_OPT_TST(o, REVERSE_DIFF)) { - unsigned tmp; - const char *tmp_c; - tmp = mode1; mode1 = mode2; mode2 = tmp; - tmp_c = name1; name1 = name2; name2 = tmp_c; - } - - if (!name1) - name1 = "/dev/null"; - if (!name2) - name2 = "/dev/null"; - d1 = alloc_filespec(name1); - d2 = alloc_filespec(name2); - fill_filespec(d1, null_sha1, mode1); - fill_filespec(d2, null_sha1, mode2); - - diff_queue(&diff_queued_diff, d1, d2); - return 0; - } -} - -/* - * Does the path name a blob in the working tree, or a directory - * in the working tree? - */ -static int is_in_index(const char *path) -{ - int len, pos; - struct cache_entry *ce; - - len = strlen(path); - while (path[len-1] == '/') - len--; - if (!len) - return 1; /* "." */ - pos = cache_name_pos(path, len); - if (0 <= pos) - return 1; - pos = -1 - pos; - while (pos < active_nr) { - ce = active_cache[pos++]; - if (ce_namelen(ce) <= len || - strncmp(ce->name, path, len) || - (ce->name[len] > '/')) - break; /* path cannot be a prefix */ - if (ce->name[len] == '/') - return 1; - } - return 0; -} - -static int handle_diff_files_args(struct rev_info *revs, - int argc, const char **argv, - unsigned int *options) -{ - *options = 0; - - /* revs->max_count == -2 means --no-index */ - while (1 < argc && argv[1][0] == '-') { - if (!strcmp(argv[1], "--base")) - revs->max_count = 1; - else if (!strcmp(argv[1], "--ours")) - revs->max_count = 2; - else if (!strcmp(argv[1], "--theirs")) - revs->max_count = 3; - else if (!strcmp(argv[1], "-n") || - !strcmp(argv[1], "--no-index")) { - revs->max_count = -2; - DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); - DIFF_OPT_SET(&revs->diffopt, NO_INDEX); - } - else if (!strcmp(argv[1], "-q")) - *options |= DIFF_SILENT_ON_REMOVED; - else - return error("invalid option: %s", argv[1]); - argv++; argc--; - } - - if (revs->max_count == -1 && revs->diffopt.nr_paths == 2) { - /* - * If two files are specified, and at least one is untracked, - * default to no-index. - */ - read_cache(); - if (!is_in_index(revs->diffopt.paths[0]) || - !is_in_index(revs->diffopt.paths[1])) { - revs->max_count = -2; - DIFF_OPT_SET(&revs->diffopt, NO_INDEX); - } - } - - /* - * Make sure there are NO revision (i.e. pending object) parameter, - * rev.max_count is reasonable (0 <= n <= 3), - * there is no other revision filtering parameters. - */ - if (revs->pending.nr || revs->max_count > 3 || - revs->min_age != -1 || revs->max_age != -1) - return error("no revision allowed with diff-files"); - - if (revs->max_count == -1 && - (revs->diffopt.output_format & DIFF_FORMAT_PATCH)) - revs->combine_merges = revs->dense_combined_merges = 1; - - return 0; -} - -static int is_outside_repo(const char *path, int nongit, const char *prefix) -{ - int i; - if (nongit || !strcmp(path, "-") || is_absolute_path(path)) - return 1; - if (prefixcmp(path, "../")) - return 0; - if (!prefix) - return 1; - for (i = strlen(prefix); !prefixcmp(path, "../"); ) { - while (i > 0 && prefix[i - 1] != '/') - i--; - if (--i < 0) - return 1; - path += 3; - } - return 0; -} - -int setup_diff_no_index(struct rev_info *revs, - int argc, const char ** argv, int nongit, const char *prefix) -{ - int i; - for (i = 1; i < argc; i++) - if (argv[i][0] != '-' || argv[i][1] == '\0') - break; - else if (!strcmp(argv[i], "--")) { - i++; - break; - } else if (i < argc - 3 && !strcmp(argv[i], "--no-index")) { - i = argc - 3; - DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); - break; - } - if (nongit && argc != i + 2) - die("git diff [--no-index] takes two paths"); - - if (argc != i + 2 || (!is_outside_repo(argv[i + 1], nongit, prefix) && - !is_outside_repo(argv[i], nongit, prefix))) - return -1; - - diff_setup(&revs->diffopt); - for (i = 1; i < argc - 2; ) - if (!strcmp(argv[i], "--no-index")) - i++; - else { - int j = diff_opt_parse(&revs->diffopt, - argv + i, argc - i); - if (!j) - die("invalid diff option/value: %s", argv[i]); - i += j; - } - - if (prefix) { - int len = strlen(prefix); - - revs->diffopt.paths = xcalloc(2, sizeof(char*)); - for (i = 0; i < 2; i++) { - const char *p = argv[argc - 2 + i]; - /* - * stdin should be spelled as '-'; if you have - * path that is '-', spell it as ./-. - */ - p = (strcmp(p, "-") - ? xstrdup(prefix_filename(prefix, len, p)) - : p); - revs->diffopt.paths[i] = p; - } - } - else - revs->diffopt.paths = argv + argc - 2; - revs->diffopt.nr_paths = 2; - DIFF_OPT_SET(&revs->diffopt, NO_INDEX); - revs->max_count = -2; - if (diff_setup_done(&revs->diffopt) < 0) - die("diff_setup_done failed"); - return 0; -} - -int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) -{ - unsigned int options; - - if (handle_diff_files_args(revs, argc, argv, &options)) - return -1; - - if (DIFF_OPT_TST(&revs->diffopt, NO_INDEX)) { - if (revs->diffopt.nr_paths != 2) - return error("need two files/directories with --no-index"); - if (queue_diff(&revs->diffopt, revs->diffopt.paths[0], - revs->diffopt.paths[1])) - return -1; - diffcore_std(&revs->diffopt); - diff_flush(&revs->diffopt); - /* - * The return code for --no-index imitates diff(1): - * 0 = no changes, 1 = changes, else error - */ - return revs->diffopt.found_changes; - } - - if (read_cache() < 0) { - perror("read_cache"); - return -1; - } - return run_diff_files(revs, options); -} - /* * Has the work tree entity been removed? * diff --git a/diff-no-index.c b/diff-no-index.c new file mode 100644 index 0000000000..1b57feeb24 --- /dev/null +++ b/diff-no-index.c @@ -0,0 +1,231 @@ +/* + * "diff --no-index" support + * Copyright (c) 2007 by Johannes Schindelin + * Copyright (c) 2008 by Junio C Hamano + */ + +#include "cache.h" +#include "color.h" +#include "commit.h" +#include "blob.h" +#include "tag.h" +#include "diff.h" +#include "diffcore.h" +#include "revision.h" +#include "log-tree.h" +#include "builtin.h" +#include "path-list.h" + +static int read_directory(const char *path, struct path_list *list) +{ + DIR *dir; + struct dirent *e; + + if (!(dir = opendir(path))) + return error("Could not open directory %s", path); + + while ((e = readdir(dir))) + if (strcmp(".", e->d_name) && strcmp("..", e->d_name)) + path_list_insert(e->d_name, list); + + closedir(dir); + return 0; +} + +static int get_mode(const char *path, int *mode) +{ + struct stat st; + + if (!path || !strcmp(path, "/dev/null")) + *mode = 0; + else if (!strcmp(path, "-")) + *mode = create_ce_mode(0666); + else if (stat(path, &st)) + return error("Could not access '%s'", path); + else + *mode = st.st_mode; + return 0; +} + +static int queue_diff(struct diff_options *o, + const char *name1, const char *name2) +{ + int mode1 = 0, mode2 = 0; + + if (get_mode(name1, &mode1) || get_mode(name2, &mode2)) + return -1; + + if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2)) + return error("file/directory conflict: %s, %s", name1, name2); + + if (S_ISDIR(mode1) || S_ISDIR(mode2)) { + char buffer1[PATH_MAX], buffer2[PATH_MAX]; + struct path_list p1 = {NULL, 0, 0, 1}, p2 = {NULL, 0, 0, 1}; + int len1 = 0, len2 = 0, i1, i2, ret = 0; + + if (name1 && read_directory(name1, &p1)) + return -1; + if (name2 && read_directory(name2, &p2)) { + path_list_clear(&p1, 0); + return -1; + } + + if (name1) { + len1 = strlen(name1); + if (len1 > 0 && name1[len1 - 1] == '/') + len1--; + memcpy(buffer1, name1, len1); + buffer1[len1++] = '/'; + } + + if (name2) { + len2 = strlen(name2); + if (len2 > 0 && name2[len2 - 1] == '/') + len2--; + memcpy(buffer2, name2, len2); + buffer2[len2++] = '/'; + } + + for (i1 = i2 = 0; !ret && (i1 < p1.nr || i2 < p2.nr); ) { + const char *n1, *n2; + int comp; + + if (i1 == p1.nr) + comp = 1; + else if (i2 == p2.nr) + comp = -1; + else + comp = strcmp(p1.items[i1].path, + p2.items[i2].path); + + if (comp > 0) + n1 = NULL; + else { + n1 = buffer1; + strncpy(buffer1 + len1, p1.items[i1++].path, + PATH_MAX - len1); + } + + if (comp < 0) + n2 = NULL; + else { + n2 = buffer2; + strncpy(buffer2 + len2, p2.items[i2++].path, + PATH_MAX - len2); + } + + ret = queue_diff(o, n1, n2); + } + path_list_clear(&p1, 0); + path_list_clear(&p2, 0); + + return ret; + } else { + struct diff_filespec *d1, *d2; + + if (DIFF_OPT_TST(o, REVERSE_DIFF)) { + unsigned tmp; + const char *tmp_c; + tmp = mode1; mode1 = mode2; mode2 = tmp; + tmp_c = name1; name1 = name2; name2 = tmp_c; + } + + if (!name1) + name1 = "/dev/null"; + if (!name2) + name2 = "/dev/null"; + d1 = alloc_filespec(name1); + d2 = alloc_filespec(name2); + fill_filespec(d1, null_sha1, mode1); + fill_filespec(d2, null_sha1, mode2); + + diff_queue(&diff_queued_diff, d1, d2); + return 0; + } +} + +void diff_no_index(struct rev_info *revs, + int argc, const char **argv, + int nongit, const char *prefix) +{ + int i; + int no_index = 0; + unsigned options = 0; + + /* Were we asked to do --no-index explicitly? */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "--")) + return; + if (!strcmp(argv[i], "--no-index")) + no_index = 1; + if (argv[i][0] != '-') + break; + } + + /* + * No explicit --no-index, but "git diff --opts A B" outside + * a git repository is a cute hack to support. + */ + if (!no_index && !nongit) + return; + + if (argc != i + 2) + die("git diff %s takes two paths", + no_index ? "--no-index" : "[--no-index]"); + + diff_setup(&revs->diffopt); + if (!revs->diffopt.output_format) + revs->diffopt.output_format = DIFF_FORMAT_PATCH; + for (i = 1; i < argc - 2; ) { + int j; + if (!strcmp(argv[i], "--no-index")) + i++; + else if (!strcmp(argv[1], "-q")) + options |= DIFF_SILENT_ON_REMOVED; + else { + j = diff_opt_parse(&revs->diffopt, argv + i, argc - i); + if (!j) + die("invalid diff option/value: %s", argv[i]); + i += j; + } + } + + if (prefix) { + int len = strlen(prefix); + + revs->diffopt.paths = xcalloc(2, sizeof(char*)); + for (i = 0; i < 2; i++) { + const char *p = argv[argc - 2 + i]; + /* + * stdin should be spelled as '-'; if you have + * path that is '-', spell it as ./-. + */ + p = (strcmp(p, "-") + ? xstrdup(prefix_filename(prefix, len, p)) + : p); + revs->diffopt.paths[i] = p; + } + } + else + revs->diffopt.paths = argv + argc - 2; + revs->diffopt.nr_paths = 2; + + DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS); + DIFF_OPT_SET(&revs->diffopt, NO_INDEX); + + revs->max_count = -2; + if (diff_setup_done(&revs->diffopt) < 0) + die("diff_setup_done failed"); + + if (queue_diff(&revs->diffopt, revs->diffopt.paths[0], + revs->diffopt.paths[1])) + exit(1); + diffcore_std(&revs->diffopt); + diff_flush(&revs->diffopt); + + /* + * The return code for --no-index imitates diff(1): + * 0 = no changes, 1 = changes, else error + */ + exit(revs->diffopt.found_changes); +} diff --git a/diff.h b/diff.h index 3a02d38d12..e019730638 100644 --- a/diff.h +++ b/diff.h @@ -250,10 +250,6 @@ extern const char *diff_unique_abbrev(const unsigned char *, int); /* report racily-clean paths as modified */ #define DIFF_RACY_IS_MODIFIED 02 extern int run_diff_files(struct rev_info *revs, unsigned int option); -extern int setup_diff_no_index(struct rev_info *revs, - int argc, const char ** argv, int nongit, const char *prefix); -extern int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv); - extern int run_diff_index(struct rev_info *revs, int cached); extern int do_diff_cache(const unsigned char *, struct diff_options *); @@ -261,4 +257,6 @@ extern int diff_flush_patch_id(struct diff_options *, unsigned char *); extern int diff_result_code(struct diff_options *, int); +extern void diff_no_index(struct rev_info *, int, const char **, int, const char *); + #endif /* DIFF_H */ diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 4c038ccec1..9337b81064 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -257,6 +257,7 @@ diff --patch-with-raw initial..side diff --patch-with-stat -r initial..side diff --patch-with-raw -r initial..side diff --name-status dir2 dir +diff --no-index --name-status dir2 dir EOF test_done diff --git a/t/t4013/diff.diff_--name-status_dir2_dir b/t/t4013/diff.diff_--name-status_dir2_dir index ef7fdb7335..d0d96aaa91 100644 --- a/t/t4013/diff.diff_--name-status_dir2_dir +++ b/t/t4013/diff.diff_--name-status_dir2_dir @@ -1,3 +1,2 @@ $ git diff --name-status dir2 dir -A dir/sub $ diff --git a/t/t4013/diff.diff_--no-index_--name-status_dir2_dir b/t/t4013/diff.diff_--no-index_--name-status_dir2_dir new file mode 100644 index 0000000000..6a47584777 --- /dev/null +++ b/t/t4013/diff.diff_--no-index_--name-status_dir2_dir @@ -0,0 +1,3 @@ +$ git diff --no-index --name-status dir2 dir +A dir/sub +$ -- cgit v1.3 From fd55a19eb1d49ae54008d932a65f79cd6fda45c9 Mon Sep 17 00:00:00 2001 From: Dmitry Potapov Date: Wed, 16 Jul 2008 18:54:02 +0400 Subject: Fix buffer overflow in git diff If PATH_MAX on your system is smaller than a path stored, it may cause buffer overflow and stack corruption in diff_addremove() and diff_change() functions when running git-diff Signed-off-by: Dmitry Potapov Signed-off-by: Junio C Hamano --- diff-lib.c | 8 ++++---- diff.c | 11 ++--------- diff.h | 9 ++++----- revision.c | 4 ++-- tree-diff.c | 27 ++++++++++++++++++++++----- 5 files changed, 34 insertions(+), 25 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index b17722d66a..e7eaff9a68 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -171,7 +171,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) if (silent_on_removed) continue; diff_addremove(&revs->diffopt, '-', ce->ce_mode, - ce->sha1, ce->name, NULL); + ce->sha1, ce->name); continue; } changed = ce_match_stat(ce, &st, ce_option); @@ -184,7 +184,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) newmode = ce_mode_from_stat(ce, st.st_mode); diff_change(&revs->diffopt, oldmode, newmode, ce->sha1, (changed ? null_sha1 : ce->sha1), - ce->name, NULL); + ce->name); } diffcore_std(&revs->diffopt); @@ -208,7 +208,7 @@ static void diff_index_show_file(struct rev_info *revs, const unsigned char *sha1, unsigned int mode) { diff_addremove(&revs->diffopt, prefix[0], mode, - sha1, ce->name, NULL); + sha1, ce->name); } static int get_stat_data(struct cache_entry *ce, @@ -312,7 +312,7 @@ static int show_modified(struct oneway_unpack_data *cbdata, return 0; diff_change(&revs->diffopt, oldmode, mode, - old->sha1, sha1, old->name, NULL); + old->sha1, sha1, old->name); return 0; } diff --git a/diff.c b/diff.c index 78c4d3a35a..386de826d3 100644 --- a/diff.c +++ b/diff.c @@ -3356,9 +3356,8 @@ int diff_result_code(struct diff_options *opt, int status) void diff_addremove(struct diff_options *options, int addremove, unsigned mode, const unsigned char *sha1, - const char *base, const char *path) + const char *concatpath) { - char concatpath[PATH_MAX]; struct diff_filespec *one, *two; if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(mode)) @@ -3380,9 +3379,6 @@ void diff_addremove(struct diff_options *options, addremove = (addremove == '+' ? '-' : addremove == '-' ? '+' : addremove); - if (!path) path = ""; - sprintf(concatpath, "%s%s", base, path); - if (options->prefix && strncmp(concatpath, options->prefix, options->prefix_length)) return; @@ -3403,9 +3399,8 @@ void diff_change(struct diff_options *options, unsigned old_mode, unsigned new_mode, const unsigned char *old_sha1, const unsigned char *new_sha1, - const char *base, const char *path) + const char *concatpath) { - char concatpath[PATH_MAX]; struct diff_filespec *one, *two; if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(old_mode) @@ -3418,8 +3413,6 @@ void diff_change(struct diff_options *options, tmp = old_mode; old_mode = new_mode; new_mode = tmp; tmp_c = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_c; } - if (!path) path = ""; - sprintf(concatpath, "%s%s", base, path); if (options->prefix && strncmp(concatpath, options->prefix, options->prefix_length)) diff --git a/diff.h b/diff.h index 5dc0cb595b..50fb5ddb0b 100644 --- a/diff.h +++ b/diff.h @@ -14,12 +14,12 @@ typedef void (*change_fn_t)(struct diff_options *options, unsigned old_mode, unsigned new_mode, const unsigned char *old_sha1, const unsigned char *new_sha1, - const char *base, const char *path); + const char *fullpath); typedef void (*add_remove_fn_t)(struct diff_options *options, int addremove, unsigned mode, const unsigned char *sha1, - const char *base, const char *path); + const char *fullpath); typedef void (*diff_format_fn_t)(struct diff_queue_struct *q, struct diff_options *options, void *data); @@ -164,14 +164,13 @@ extern void diff_addremove(struct diff_options *, int addremove, unsigned mode, const unsigned char *sha1, - const char *base, - const char *path); + const char *fullpath); extern void diff_change(struct diff_options *, unsigned mode1, unsigned mode2, const unsigned char *sha1, const unsigned char *sha2, - const char *base, const char *path); + const char *fullpath); extern void diff_unmerge(struct diff_options *, const char *path, diff --git a/revision.c b/revision.c index fc66755259..8dc3ca7bf6 100644 --- a/revision.c +++ b/revision.c @@ -259,7 +259,7 @@ static int tree_difference = REV_TREE_SAME; static void file_add_remove(struct diff_options *options, int addremove, unsigned mode, const unsigned char *sha1, - const char *base, const char *path) + const char *fullpath) { int diff = REV_TREE_DIFFERENT; @@ -285,7 +285,7 @@ static void file_change(struct diff_options *options, unsigned old_mode, unsigned new_mode, const unsigned char *old_sha1, const unsigned char *new_sha1, - const char *base, const char *path) + const char *fullpath) { tree_difference = REV_TREE_DIFFERENT; DIFF_OPT_SET(options, HAS_CHANGES); diff --git a/tree-diff.c b/tree-diff.c index e1e2e6c6ce..bbb126fc46 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -15,6 +15,15 @@ static char *malloc_base(const char *base, int baselen, const char *path, int pa return newbase; } +static char *malloc_fullname(const char *base, int baselen, const char *path, int pathlen) +{ + char *fullname = xmalloc(baselen + pathlen + 1); + memcpy(fullname, base, baselen); + memcpy(fullname + baselen, path, pathlen); + fullname[baselen + pathlen] = 0; + return fullname; +} + static void show_entry(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base, int baselen); @@ -24,6 +33,7 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const const char *path1, *path2; const unsigned char *sha1, *sha2; int cmp, pathlen1, pathlen2; + char *fullname; sha1 = tree_entry_extract(t1, &path1, &mode1); sha2 = tree_entry_extract(t2, &path2, &mode2); @@ -55,15 +65,20 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode1)) { int retval; char *newbase = malloc_base(base, baselen, path1, pathlen1); - if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) + if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) { + newbase[baselen + pathlen1] = 0; opt->change(opt, mode1, mode2, - sha1, sha2, base, path1); + sha1, sha2, newbase); + newbase[baselen + pathlen1] = '/'; + } retval = diff_tree_sha1(sha1, sha2, newbase, opt); free(newbase); return retval; } - opt->change(opt, mode1, mode2, sha1, sha2, base, path1); + fullname = malloc_fullname(base, baselen, path1, pathlen1); + opt->change(opt, mode1, mode2, sha1, sha2, fullname); + free(fullname); return 0; } @@ -205,10 +220,10 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree unsigned mode; const char *path; const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode); + int pathlen = tree_entry_len(path, sha1); if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode)) { enum object_type type; - int pathlen = tree_entry_len(path, sha1); char *newbase = malloc_base(base, baselen, path, pathlen); struct tree_desc inner; void *tree; @@ -224,7 +239,9 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree free(tree); free(newbase); } else { - opt->add_remove(opt, prefix[0], mode, sha1, base, path); + char *fullname = malloc_fullname(base, baselen, path, pathlen); + opt->add_remove(opt, prefix[0], mode, sha1, fullname); + free(fullname); } } -- cgit v1.3 From a5a818ee4877e4458e8e6741a03ac3b19941d58a Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 18 Aug 2008 20:08:09 -0700 Subject: diff: vary default prefix depending on what are compared With a new configuration "diff.mnemonicprefix", "git diff" shows the differences between various combinations of preimage and postimage trees with prefixes different from the standard "a/" and "b/". Hopefully this will make the distinction stand out for some people. "git diff" compares the (i)ndex and the (w)ork tree; "git diff HEAD" compares a (c)ommit and the (w)ork tree; "git diff --cached" compares a (c)ommit and the (i)ndex; "git-diff HEAD:file1 file2" compares an (o)bject and a (w)ork tree entity; "git diff --no-index a b" compares two non-git things (1) and (2). Because these mnemonics now have meanings, they are swapped when reverse diff is in effect and this feature is enabled. Signed-off-by: Junio C Hamano --- Documentation/config.txt | 16 ++++++++++++++++ builtin-diff.c | 2 ++ combine-diff.c | 8 ++++++-- diff-lib.c | 3 +++ diff-no-index.c | 1 + diff.c | 46 ++++++++++++++++++++++++++++++++++++++++------ diff.h | 2 ++ 7 files changed, 70 insertions(+), 8 deletions(-) (limited to 'diff-lib.c') diff --git a/Documentation/config.txt b/Documentation/config.txt index 81f981509a..74af36de5c 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -581,6 +581,22 @@ diff.external:: you want to use an external diff program only on a subset of your files, you might want to use linkgit:gitattributes[5] instead. +diff.mnemonicprefix:: + If set, 'git-diff' uses a prefix pair that is different from the + standard "a/" and "b/" depending on what is being compared. When + this configuration is in effect, reverse diff output also swaps + the order of the prefixes: +'git-diff';; + compares the (i)ndex and the (w)ork tree; +'git-diff HEAD';; + compares a (c)ommit and the (w)ork tree; +'git diff --cached';; + compares a (c)ommit and the (i)ndex; +'git-diff HEAD:file1 file2';; + compares an (o)bject and a (w)ork tree entity; +'git diff --no-index a b';; + compares two non-git things (1) and (2). + diff.renameLimit:: The number of files to consider when performing the copy/rename detection; equivalent to the 'git-diff' option '-l'. diff --git a/builtin-diff.c b/builtin-diff.c index 7ffea97505..266337b832 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -74,6 +74,8 @@ static int builtin_diff_b_f(struct rev_info *revs, if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode))) die("'%s': not a regular file or symlink", path); + diff_set_mnemonic_prefix(&revs->diffopt, "o/", "w/"); + if (blob[0].mode == S_IFINVALID) blob[0].mode = canon_mode(st.st_mode); diff --git a/combine-diff.c b/combine-diff.c index 4dfc330867..19bd60e346 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -675,9 +675,13 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, int i, show_hunks; int working_tree_file = is_null_sha1(elem->sha1); int abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? 40 : DEFAULT_ABBREV; + const char *a_prefix, *b_prefix; mmfile_t result_file; context = opt->context; + a_prefix = opt->a_prefix ? opt->a_prefix : "a/"; + b_prefix = opt->b_prefix ? opt->b_prefix : "b/"; + /* Read the result of merge first */ if (!working_tree_file) result = grab_blob(elem->sha1, &result_size); @@ -853,13 +857,13 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, dump_quoted_path("--- ", "", "/dev/null", c_meta, c_reset); else - dump_quoted_path("--- ", opt->a_prefix, elem->path, + dump_quoted_path("--- ", a_prefix, elem->path, c_meta, c_reset); if (deleted) dump_quoted_path("+++ ", "", "/dev/null", c_meta, c_reset); else - dump_quoted_path("+++ ", opt->b_prefix, elem->path, + dump_quoted_path("+++ ", b_prefix, elem->path, c_meta, c_reset); dump_sline(sline, cnt, num_parent, DIFF_OPT_TST(opt, COLOR_DIFF)); diff --git a/diff-lib.c b/diff-lib.c index e7eaff9a68..ae96c64ca2 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -63,6 +63,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option) ? CE_MATCH_RACY_IS_DIRTY : 0); char symcache[PATH_MAX]; + diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/"); + if (diff_unmerged_stage < 0) diff_unmerged_stage = 2; entries = active_nr; @@ -469,6 +471,7 @@ int run_diff_index(struct rev_info *revs, int cached) if (unpack_trees(1, &t, &opts)) exit(128); + diff_set_mnemonic_prefix(&revs->diffopt, "c/", cached ? "i/" : "w/"); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); return 0; diff --git a/diff-no-index.c b/diff-no-index.c index 7d68b7f1be..b60d3455da 100644 --- a/diff-no-index.c +++ b/diff-no-index.c @@ -252,6 +252,7 @@ void diff_no_index(struct rev_info *revs, if (queue_diff(&revs->diffopt, revs->diffopt.paths[0], revs->diffopt.paths[1])) exit(1); + diff_set_mnemonic_prefix(&revs->diffopt, "1/", "2/"); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); diff --git a/diff.c b/diff.c index 7b4300a74a..c1804efed9 100644 --- a/diff.c +++ b/diff.c @@ -23,6 +23,7 @@ static int diff_rename_limit_default = 200; int diff_use_color_default = -1; static const char *external_diff_cmd_cfg; int diff_auto_refresh_index = 1; +static int diff_mnemonic_prefix; static char diff_colors[][COLOR_MAXLEN] = { "\033[m", /* reset */ @@ -149,6 +150,10 @@ int git_diff_ui_config(const char *var, const char *value, void *cb) diff_auto_refresh_index = git_config_bool(var, value); return 0; } + if (!strcmp(var, "diff.mnemonicprefix")) { + diff_mnemonic_prefix = git_config_bool(var, value); + return 0; + } if (!strcmp(var, "diff.external")) return git_config_string(&external_diff_cmd_cfg, var, value); if (!prefixcmp(var, "diff.")) { @@ -305,6 +310,15 @@ static void emit_rewrite_diff(const char *name_a, const char *new = diff_get_color(color_diff, DIFF_FILE_NEW); const char *reset = diff_get_color(color_diff, DIFF_RESET); static struct strbuf a_name = STRBUF_INIT, b_name = STRBUF_INIT; + const char *a_prefix, *b_prefix; + + if (diff_mnemonic_prefix && DIFF_OPT_TST(o, REVERSE_DIFF)) { + a_prefix = o->b_prefix; + b_prefix = o->a_prefix; + } else { + a_prefix = o->a_prefix; + b_prefix = o->b_prefix; + } name_a += (*name_a == '/'); name_b += (*name_b == '/'); @@ -313,8 +327,8 @@ static void emit_rewrite_diff(const char *name_a, strbuf_reset(&a_name); strbuf_reset(&b_name); - quote_two_c_style(&a_name, o->a_prefix, name_a, 0); - quote_two_c_style(&b_name, o->b_prefix, name_b, 0); + quote_two_c_style(&a_name, a_prefix, name_a, 0); + quote_two_c_style(&b_name, b_prefix, name_b, 0); diff_populate_filespec(one, 0); diff_populate_filespec(two, 0); @@ -1432,6 +1446,14 @@ static const char *diff_funcname_pattern(struct diff_filespec *one) return NULL; } +void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b) +{ + if (!options->a_prefix) + options->a_prefix = a; + if (!options->b_prefix) + options->b_prefix = b; +} + static void builtin_diff(const char *name_a, const char *name_b, struct diff_filespec *one, @@ -1445,9 +1467,19 @@ static void builtin_diff(const char *name_a, char *a_one, *b_two; const char *set = diff_get_color_opt(o, DIFF_METAINFO); const char *reset = diff_get_color_opt(o, DIFF_RESET); + const char *a_prefix, *b_prefix; + + diff_set_mnemonic_prefix(o, "a/", "b/"); + if (DIFF_OPT_TST(o, REVERSE_DIFF)) { + a_prefix = o->b_prefix; + b_prefix = o->a_prefix; + } else { + a_prefix = o->a_prefix; + b_prefix = o->b_prefix; + } - a_one = quote_two(o->a_prefix, name_a + (*name_a == '/')); - b_two = quote_two(o->b_prefix, name_b + (*name_b == '/')); + a_one = quote_two(a_prefix, name_a + (*name_a == '/')); + b_two = quote_two(b_prefix, name_b + (*name_b == '/')); lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null"; lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null"; fprintf(o->file, "%sdiff --git %s %s%s\n", set, a_one, b_two, reset); @@ -2308,8 +2340,10 @@ void diff_setup(struct diff_options *options) DIFF_OPT_CLR(options, COLOR_DIFF); options->detect_rename = diff_detect_rename_default; - options->a_prefix = "a/"; - options->b_prefix = "b/"; + if (!diff_mnemonic_prefix) { + options->a_prefix = "a/"; + options->b_prefix = "b/"; + } } int diff_setup_done(struct diff_options *options) diff --git a/diff.h b/diff.h index 50fb5ddb0b..9a679f58f5 100644 --- a/diff.h +++ b/diff.h @@ -160,6 +160,8 @@ extern void diff_tree_combined(const unsigned char *sha1, const unsigned char pa extern void diff_tree_combined_merge(const unsigned char *sha1, int, struct rev_info *); +void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b); + extern void diff_addremove(struct diff_options *, int addremove, unsigned mode, -- cgit v1.3 From ff7e6aad6d995a52e88cfeaae10cf8a768ff2358 Mon Sep 17 00:00:00 2001 From: Kjetil Barvik Date: Sun, 11 Jan 2009 19:36:42 +0100 Subject: Cleanup of unused symcache variable inside diff-lib.c Commit c40641b77b0274186fd1b327d5dc3246f814aaaf, 'Optimize symlink/directory detection' by Linus Torvalds, removed the 'char *symcache' parameter to the has_symlink_leading_path() function. This made all variables currently named 'symcache' inside diff-lib.c unnecessary. This also let us throw away the 'struct oneway_unpack_data', and instead directly use the 'struct rev_info *revs' member, which was the only member left after removal of the 'symcache[] array' member. The 'struct oneway_unpack_data' was introduced by the following commit: 948dd346 "diff-files: careful when inspecting work tree items" Impact: cleanup PATH_MAX bytes less memory stack usage in some cases Signed-off-by: Kjetil Barvik Signed-off-by: Junio C Hamano --- diff-lib.c | 40 +++++++++++----------------------------- 1 file changed, 11 insertions(+), 29 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index ae96c64ca2..a41e1ec07c 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -61,14 +61,12 @@ int run_diff_files(struct rev_info *revs, unsigned int option) int silent_on_removed = option & DIFF_SILENT_ON_REMOVED; unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED) ? CE_MATCH_RACY_IS_DIRTY : 0); - char symcache[PATH_MAX]; diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/"); if (diff_unmerged_stage < 0) diff_unmerged_stage = 2; entries = active_nr; - symcache[0] = '\0'; for (i = 0; i < entries; i++) { struct stat st; unsigned int oldmode, newmode; @@ -198,11 +196,6 @@ int run_diff_files(struct rev_info *revs, unsigned int option) * diff-index */ -struct oneway_unpack_data { - struct rev_info *revs; - char symcache[PATH_MAX]; -}; - /* A file entry went away or appeared */ static void diff_index_show_file(struct rev_info *revs, const char *prefix, @@ -216,8 +209,7 @@ static void diff_index_show_file(struct rev_info *revs, static int get_stat_data(struct cache_entry *ce, const unsigned char **sha1p, unsigned int *modep, - int cached, int match_missing, - struct oneway_unpack_data *cbdata) + int cached, int match_missing) { const unsigned char *sha1 = ce->sha1; unsigned int mode = ce->ce_mode; @@ -248,25 +240,24 @@ static int get_stat_data(struct cache_entry *ce, return 0; } -static void show_new_file(struct oneway_unpack_data *cbdata, +static void show_new_file(struct rev_info *revs, struct cache_entry *new, int cached, int match_missing) { const unsigned char *sha1; unsigned int mode; - struct rev_info *revs = cbdata->revs; /* * New file in the index: it might actually be different in * the working copy. */ - if (get_stat_data(new, &sha1, &mode, cached, match_missing, cbdata) < 0) + if (get_stat_data(new, &sha1, &mode, cached, match_missing) < 0) return; diff_index_show_file(revs, "+", new, sha1, mode); } -static int show_modified(struct oneway_unpack_data *cbdata, +static int show_modified(struct rev_info *revs, struct cache_entry *old, struct cache_entry *new, int report_missing, @@ -274,9 +265,8 @@ static int show_modified(struct oneway_unpack_data *cbdata, { unsigned int mode, oldmode; const unsigned char *sha1; - struct rev_info *revs = cbdata->revs; - if (get_stat_data(new, &sha1, &mode, cached, match_missing, cbdata) < 0) { + if (get_stat_data(new, &sha1, &mode, cached, match_missing) < 0) { if (report_missing) diff_index_show_file(revs, "-", old, old->sha1, old->ce_mode); @@ -344,8 +334,7 @@ static void do_oneway_diff(struct unpack_trees_options *o, struct cache_entry *idx, struct cache_entry *tree) { - struct oneway_unpack_data *cbdata = o->unpack_data; - struct rev_info *revs = cbdata->revs; + struct rev_info *revs = o->unpack_data; int match_missing, cached; /* @@ -368,7 +357,7 @@ static void do_oneway_diff(struct unpack_trees_options *o, * Something added to the tree? */ if (!tree) { - show_new_file(cbdata, idx, cached, match_missing); + show_new_file(revs, idx, cached, match_missing); return; } @@ -381,7 +370,7 @@ static void do_oneway_diff(struct unpack_trees_options *o, } /* Show difference between old and new */ - show_modified(cbdata, tree, idx, 1, cached, match_missing); + show_modified(revs, tree, idx, 1, cached, match_missing); } static inline void skip_same_name(struct cache_entry *ce, struct unpack_trees_options *o) @@ -418,8 +407,7 @@ static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o) { struct cache_entry *idx = src[0]; struct cache_entry *tree = src[1]; - struct oneway_unpack_data *cbdata = o->unpack_data; - struct rev_info *revs = cbdata->revs; + struct rev_info *revs = o->unpack_data; if (idx && ce_stage(idx)) skip_same_name(idx, o); @@ -446,7 +434,6 @@ int run_diff_index(struct rev_info *revs, int cached) const char *tree_name; struct unpack_trees_options opts; struct tree_desc t; - struct oneway_unpack_data unpack_cb; mark_merge_entries(); @@ -456,14 +443,12 @@ int run_diff_index(struct rev_info *revs, int cached) if (!tree) return error("bad tree object %s", tree_name); - unpack_cb.revs = revs; - unpack_cb.symcache[0] = '\0'; memset(&opts, 0, sizeof(opts)); opts.head_idx = 1; opts.index_only = cached; opts.merge = 1; opts.fn = oneway_diff; - opts.unpack_data = &unpack_cb; + opts.unpack_data = revs; opts.src_index = &the_index; opts.dst_index = NULL; @@ -486,7 +471,6 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) struct cache_entry *last = NULL; struct unpack_trees_options opts; struct tree_desc t; - struct oneway_unpack_data unpack_cb; /* * This is used by git-blame to run diff-cache internally; @@ -515,14 +499,12 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) if (!tree) die("bad tree object %s", sha1_to_hex(tree_sha1)); - unpack_cb.revs = &revs; - unpack_cb.symcache[0] = '\0'; memset(&opts, 0, sizeof(opts)); opts.head_idx = 1; opts.index_only = 1; opts.merge = 1; opts.fn = oneway_diff; - opts.unpack_data = &unpack_cb; + opts.unpack_data = &revs; opts.src_index = &the_index; opts.dst_index = &the_index; -- cgit v1.3 From 571998921d8fd4ee674545406aabb86987921252 Mon Sep 17 00:00:00 2001 From: Kjetil Barvik Date: Mon, 9 Feb 2009 21:54:06 +0100 Subject: lstat_cache(): swap func(length, string) into func(string, length) Swap function argument pair (length, string) into (string, length) to conform with the commonly used order inside the GIT source code. Also, add a note about this fact into the coding guidelines. Signed-off-by: Kjetil Barvik Signed-off-by: Junio C Hamano --- Documentation/CodingGuidelines | 3 +++ builtin-add.c | 2 +- builtin-apply.c | 2 +- builtin-update-index.c | 2 +- cache.h | 8 ++++---- diff-lib.c | 2 +- dir.c | 2 +- entry.c | 2 +- symlinks.c | 16 ++++++++-------- unpack-trees.c | 4 ++-- 10 files changed, 23 insertions(+), 20 deletions(-) (limited to 'diff-lib.c') diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines index 0d7fa9cca9..b8bf618a30 100644 --- a/Documentation/CodingGuidelines +++ b/Documentation/CodingGuidelines @@ -129,3 +129,6 @@ For C programs: used in the git core command set (unless your command is clearly separate from it, such as an importer to convert random-scm-X repositories to git). + + - When we pass pair to functions, we should try to + pass them in that order. diff --git a/builtin-add.c b/builtin-add.c index ac98c8354d..a23ad96773 100644 --- a/builtin-add.c +++ b/builtin-add.c @@ -148,7 +148,7 @@ static const char **validate_pathspec(int argc, const char **argv, const char *p if (pathspec) { const char **p; for (p = pathspec; *p; p++) { - if (has_symlink_leading_path(strlen(*p), *p)) { + if (has_symlink_leading_path(*p, strlen(*p))) { int len = prefix ? strlen(prefix) : 0; die("'%s' is beyond a symbolic link", *p + len); } diff --git a/builtin-apply.c b/builtin-apply.c index f312798af3..106be94105 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -2360,7 +2360,7 @@ static int check_to_create_blob(const char *new_name, int ok_if_exists) * In such a case, path "new_name" does not exist as * far as git is concerned. */ - if (has_symlink_leading_path(strlen(new_name), new_name)) + if (has_symlink_leading_path(new_name, strlen(new_name))) return 0; return error("%s: already exists in working directory", new_name); diff --git a/builtin-update-index.c b/builtin-update-index.c index 5604977505..6c55527513 100644 --- a/builtin-update-index.c +++ b/builtin-update-index.c @@ -195,7 +195,7 @@ static int process_path(const char *path) struct stat st; len = strlen(path); - if (has_symlink_leading_path(len, path)) + if (has_symlink_leading_path(path, len)) return error("'%s' is beyond a symbolic link", path); /* diff --git a/cache.h b/cache.h index 2d889deb26..80eeeb7db8 100644 --- a/cache.h +++ b/cache.h @@ -724,10 +724,10 @@ struct checkout { }; extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath); -extern int has_symlink_leading_path(int len, const char *name); -extern int has_symlink_or_noent_leading_path(int len, const char *name); -extern int has_dirs_only_path(int len, const char *name, int prefix_len); -extern void invalidate_lstat_cache(int len, const char *name); +extern int has_symlink_leading_path(const char *name, int len); +extern int has_symlink_or_noent_leading_path(const char *name, int len); +extern int has_dirs_only_path(const char *name, int len, int prefix_len); +extern void invalidate_lstat_cache(const char *name, int len); extern void clear_lstat_cache(void); extern struct alternate_object_database { diff --git a/diff-lib.c b/diff-lib.c index a41e1ec07c..a3ba20ee29 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -31,7 +31,7 @@ static int check_removed(const struct cache_entry *ce, struct stat *st) return -1; return 1; } - if (has_symlink_leading_path(ce_namelen(ce), ce->name)) + if (has_symlink_leading_path(ce->name, ce_namelen(ce))) return 1; if (S_ISDIR(st->st_mode)) { unsigned char sub[20]; diff --git a/dir.c b/dir.c index cfd1ea587d..8fb5226542 100644 --- a/dir.c +++ b/dir.c @@ -720,7 +720,7 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i { struct path_simplify *simplify; - if (has_symlink_leading_path(strlen(path), path)) + if (has_symlink_leading_path(path, strlen(path))) return dir->nr; simplify = create_simplify(pathspec); diff --git a/entry.c b/entry.c index 05aa58d348..bb6bdb90e3 100644 --- a/entry.c +++ b/entry.c @@ -20,7 +20,7 @@ static void create_directories(const char *path, const struct checkout *state) * we test the path components of the prefix with the * stat() function instead of the lstat() function. */ - if (has_dirs_only_path(len, buf, state->base_dir_len)) + if (has_dirs_only_path(buf, len, state->base_dir_len)) continue; /* ok, it is already a directory. */ /* diff --git a/symlinks.c b/symlinks.c index 4596aee9dc..51672868d1 100644 --- a/symlinks.c +++ b/symlinks.c @@ -70,7 +70,7 @@ static inline void reset_lstat_cache(void) * of the prefix, where the cache should use the stat() function * instead of the lstat() function to test each path component. */ -static int lstat_cache(int len, const char *name, +static int lstat_cache(const char *name, int len, int track_flags, int prefix_len_stat_func) { int match_len, last_slash, last_slash_dir, previous_slash; @@ -185,7 +185,7 @@ static int lstat_cache(int len, const char *name, * Invalidate the given 'name' from the cache, if 'name' matches * completely with the cache. */ -void invalidate_lstat_cache(int len, const char *name) +void invalidate_lstat_cache(const char *name, int len) { int match_len, previous_slash; @@ -214,9 +214,9 @@ void clear_lstat_cache(void) /* * Return non-zero if path 'name' has a leading symlink component */ -int has_symlink_leading_path(int len, const char *name) +int has_symlink_leading_path(const char *name, int len) { - return lstat_cache(len, name, + return lstat_cache(name, len, FL_SYMLINK|FL_DIR, USE_ONLY_LSTAT) & FL_SYMLINK; } @@ -225,9 +225,9 @@ int has_symlink_leading_path(int len, const char *name) * Return non-zero if path 'name' has a leading symlink component or * if some leading path component does not exists. */ -int has_symlink_or_noent_leading_path(int len, const char *name) +int has_symlink_or_noent_leading_path(const char *name, int len) { - return lstat_cache(len, name, + return lstat_cache(name, len, FL_SYMLINK|FL_NOENT|FL_DIR, USE_ONLY_LSTAT) & (FL_SYMLINK|FL_NOENT); } @@ -239,9 +239,9 @@ int has_symlink_or_noent_leading_path(int len, const char *name) * 'prefix_len', thus we then allow for symlinks in the prefix part as * long as those points to real existing directories. */ -int has_dirs_only_path(int len, const char *name, int prefix_len) +int has_dirs_only_path(const char *name, int len, int prefix_len) { - return lstat_cache(len, name, + return lstat_cache(name, len, FL_DIR|FL_FULLPATH, prefix_len) & FL_DIR; } diff --git a/unpack-trees.c b/unpack-trees.c index e547282ed5..2293158850 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -61,7 +61,7 @@ static void unlink_entry(struct cache_entry *ce) char *cp, *prev; char *name = ce->name; - if (has_symlink_or_noent_leading_path(ce_namelen(ce), ce->name)) + if (has_symlink_or_noent_leading_path(ce->name, ce_namelen(ce))) return; if (unlink(name)) return; @@ -583,7 +583,7 @@ static int verify_absent(struct cache_entry *ce, const char *action, if (o->index_only || o->reset || !o->update) return 0; - if (has_symlink_or_noent_leading_path(ce_namelen(ce), ce->name)) + if (has_symlink_or_noent_leading_path(ce->name, ce_namelen(ce))) return 0; if (!lstat(ce->name, &st)) { -- cgit v1.3 From 75f3ff2eeaba820b37016f464b6d1078cb6260e2 Mon Sep 17 00:00:00 2001 From: Stephan Beyer Date: Tue, 10 Feb 2009 15:30:35 +0100 Subject: Generalize and libify index_is_dirty() to index_differs_from(...) index_is_dirty() in builtin-revert.c checks if the index is dirty. This patch generalizes this function to check if the index differs from a revision, i.e. the former index_is_dirty() behavior can now be achieved by index_differs_from("HEAD", 0). The second argument "diff_flags" allows to set further diff option flags like DIFF_OPT_IGNORE_SUBMODULES. See DIFF_OPT_* macros in diff.h for a list. index_differs_from() seems to be useful for more than builtin-revert.c, so it is moved into diff-lib.c and also used in builtin-commit.c. Yet to mention: - "rev.abbrev = 0;" can be safely removed. This has no impact on performance or functioning of neither setup_revisions() nor run_diff_index(). - rev.pending.objects is free()d because this fixes a leak. (Also see 295dd2ad "Fix memory leak in traverse_commit_list") Mentored-by: Daniel Barkalow Mentored-by: Christian Couder Signed-off-by: Stephan Beyer Signed-off-by: Junio C Hamano --- builtin-commit.c | 13 ++----------- builtin-revert.c | 13 +------------ diff-lib.c | 15 +++++++++++++++ diff.h | 2 ++ 4 files changed, 20 insertions(+), 23 deletions(-) (limited to 'diff-lib.c') diff --git a/builtin-commit.c b/builtin-commit.c index d6a3a6203a..46e649cd7c 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -561,7 +561,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix) commitable = run_status(fp, index_file, prefix, 1); wt_status_use_color = saved_color_setting; } else { - struct rev_info rev; unsigned char sha1[20]; const char *parent = "HEAD"; @@ -573,16 +572,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix) if (get_sha1(parent, sha1)) commitable = !!active_nr; - else { - init_revisions(&rev, ""); - rev.abbrev = 0; - setup_revisions(0, NULL, &rev, parent); - DIFF_OPT_SET(&rev.diffopt, QUIET); - DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS); - run_diff_index(&rev, 1 /* cached */); - - commitable = !!DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES); - } + else + commitable = index_differs_from(parent, 0); } fclose(fp); diff --git a/builtin-revert.c b/builtin-revert.c index d48313c745..d210150671 100644 --- a/builtin-revert.c +++ b/builtin-revert.c @@ -223,17 +223,6 @@ static char *help_msg(const unsigned char *sha1) return helpbuf; } -static int index_is_dirty(void) -{ - struct rev_info rev; - init_revisions(&rev, NULL); - setup_revisions(0, NULL, &rev, "HEAD"); - DIFF_OPT_SET(&rev.diffopt, QUIET); - DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS); - run_diff_index(&rev, 1); - return !!DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES); -} - static struct tree *empty_tree(void) { struct tree *tree = xcalloc(1, sizeof(struct tree)); @@ -279,7 +268,7 @@ static int revert_or_cherry_pick(int argc, const char **argv) } else { if (get_sha1("HEAD", head)) die ("You do not have a valid HEAD"); - if (index_is_dirty()) + if (index_differs_from("HEAD", 0)) die ("Dirty index: cannot %s", me); } discard_cache(); diff --git a/diff-lib.c b/diff-lib.c index a41e1ec07c..79d0606834 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -513,3 +513,18 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) exit(128); return 0; } + +int index_differs_from(const char *def, int diff_flags) +{ + struct rev_info rev; + + init_revisions(&rev, NULL); + setup_revisions(0, NULL, &rev, def); + DIFF_OPT_SET(&rev.diffopt, QUIET); + DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS); + rev.diffopt.flags |= diff_flags; + run_diff_index(&rev, 1); + if (rev.pending.alloc) + free(rev.pending.objects); + return (DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0); +} diff --git a/diff.h b/diff.h index 23cd90c2e6..6703a4fb4f 100644 --- a/diff.h +++ b/diff.h @@ -265,4 +265,6 @@ extern int diff_result_code(struct diff_options *, int); extern void diff_no_index(struct rev_info *, int, const char **, int, const char *); +extern int index_differs_from(const char *def, int diff_flags); + #endif /* DIFF_H */ -- cgit v1.3 From 658dd48c8572d0db49719cbef6605d384621d87c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 9 May 2009 14:57:30 -0700 Subject: Avoid unnecessary 'lstat()' calls in 'get_stat_data()' When we ask get_stat_data() to get the mode and size of an index entry, we can avoid the lstat() call if we have marked the index entry as being uptodate due to earlier lstat() calls. This avoids a lot of unnecessary lstat() calls in eg 'git checkout', where the last phase shows the differences to the working tree (requiring a diff), but earlier phases have already verified the index. On the kernel repo (with a fast machine and everything cached), this changes timings of a nul 'git checkout' from - Before (best of ten): 0.14user 0.05system 0:00.19elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+13237minor)pagefaults 0swaps - After 0.11user 0.03system 0:00.15elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+13235minor)pagefaults 0swaps so it can obviously be noticeable, although equally obviously it's not a show-stopper on this particular machine. The difference is likely larger on slower machines, or with operating systems that don't do as good a job of name caching. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- diff-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index ae96c64ca2..d230efc146 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -222,7 +222,7 @@ static int get_stat_data(struct cache_entry *ce, const unsigned char *sha1 = ce->sha1; unsigned int mode = ce->ce_mode; - if (!cached) { + if (!cached && !ce_uptodate(ce)) { int changed; struct stat st; changed = check_removed(ce, &st); -- cgit v1.3 From b65982b60876c8f5f4d3b2898d5174f4812552b1 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 20 May 2009 15:57:22 -0700 Subject: Optimize "diff-index --cached" using cache-tree When running "diff-index --cached" after making a change to only a small portion of the index, there is no point unpacking unchanged subtrees into the index recursively, only to find that all entries match anyway. Tweak unpack_trees() logic that is used to read in the tree object to catch the case where the tree entry we are looking at matches the index as a whole by looking at the cache-tree. As an exercise, after modifying a few paths in the kernel tree, here are a few numbers on my Athlon 64X2 3800+: (without patch, hot cache) $ /usr/bin/time git diff --cached --raw :100644 100644 b57e1f5... e69de29... M Makefile :100644 000000 8c86b72... 0000000... D arch/x86/Makefile :000000 100644 0000000... e69de29... A arche 0.07user 0.02system 0:00.09elapsed 102%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+9407minor)pagefaults 0swaps (with patch, hot cache) $ /usr/bin/time ../git.git/git-diff --cached --raw :100644 100644 b57e1f5... e69de29... M Makefile :100644 000000 8c86b72... 0000000... D arch/x86/Makefile :000000 100644 0000000... e69de29... A arche 0.02user 0.00system 0:00.02elapsed 103%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+2446minor)pagefaults 0swaps Cold cache numbers are very impressive, but it does not matter very much in practice: (without patch, cold cache) $ su root sh -c 'echo 3 >/proc/sys/vm/drop_caches' $ /usr/bin/time git diff --cached --raw :100644 100644 b57e1f5... e69de29... M Makefile :100644 000000 8c86b72... 0000000... D arch/x86/Makefile :000000 100644 0000000... e69de29... A arche 0.06user 0.17system 0:10.26elapsed 2%CPU (0avgtext+0avgdata 0maxresident)k 247032inputs+0outputs (1172major+8237minor)pagefaults 0swaps (with patch, cold cache) $ su root sh -c 'echo 3 >/proc/sys/vm/drop_caches' $ /usr/bin/time ../git.git/git-diff --cached --raw :100644 100644 b57e1f5... e69de29... M Makefile :100644 000000 8c86b72... 0000000... D arch/x86/Makefile :000000 100644 0000000... e69de29... A arche 0.02user 0.01system 0:01.01elapsed 3%CPU (0avgtext+0avgdata 0maxresident)k 18440inputs+0outputs (79major+2369minor)pagefaults 0swaps This of course helps "git status" as well. (without patch, hot cache) $ /usr/bin/time ../git.git/git-status >/dev/null 0.17user 0.18system 0:00.35elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+5336outputs (0major+10970minor)pagefaults 0swaps (with patch, hot cache) $ /usr/bin/time ../git.git/git-status >/dev/null 0.10user 0.16system 0:00.27elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+5336outputs (0major+3921minor)pagefaults 0swaps Signed-off-by: Junio C Hamano --- cache-tree.c | 32 ++++++++++++++++++++++++++++++++ cache-tree.h | 3 +++ diff-lib.c | 2 ++ unpack-trees.c | 17 +++++++++++++++++ unpack-trees.h | 1 + 5 files changed, 55 insertions(+) (limited to 'diff-lib.c') diff --git a/cache-tree.c b/cache-tree.c index 5481e43340..16a65dfac1 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -631,3 +631,35 @@ void prime_cache_tree(struct cache_tree **it, struct tree *tree) *it = cache_tree(); prime_cache_tree_rec(*it, tree); } + +/* + * find the cache_tree that corresponds to the current level without + * exploding the full path into textual form. The root of the + * cache tree is given as "root", and our current level is "info". + * (1) When at root level, info->prev is NULL, so it is "root" itself. + * (2) Otherwise, find the cache_tree that corresponds to one level + * above us, and find ourselves in there. + */ +static struct cache_tree *find_cache_tree_from_traversal(struct cache_tree *root, + struct traverse_info *info) +{ + struct cache_tree *our_parent; + + if (!info->prev) + return root; + our_parent = find_cache_tree_from_traversal(root, info->prev); + return cache_tree_find(our_parent, info->name.path); +} + +int cache_tree_matches_traversal(struct cache_tree *root, + struct name_entry *ent, + struct traverse_info *info) +{ + struct cache_tree *it; + + it = find_cache_tree_from_traversal(root, info); + it = cache_tree_find(it, ent->path); + if (it && it->entry_count > 0 && !hashcmp(ent->sha1, it->sha1)) + return it->entry_count; + return 0; +} diff --git a/cache-tree.h b/cache-tree.h index eadcad8adc..3df641f593 100644 --- a/cache-tree.h +++ b/cache-tree.h @@ -2,6 +2,7 @@ #define CACHE_TREE_H #include "tree.h" +#include "tree-walk.h" struct cache_tree; struct cache_tree_sub { @@ -42,4 +43,6 @@ int cache_tree_update(struct cache_tree *, struct cache_entry **, int, int, int) int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix); void prime_cache_tree(struct cache_tree **, struct tree *); +extern int cache_tree_matches_traversal(struct cache_tree *, struct name_entry *ent, struct traverse_info *info); + #endif diff --git a/diff-lib.c b/diff-lib.c index a310fb2ad0..1cb97af22d 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -446,6 +446,7 @@ int run_diff_index(struct rev_info *revs, int cached) memset(&opts, 0, sizeof(opts)); opts.head_idx = 1; opts.index_only = cached; + opts.diff_index_cached = cached; opts.merge = 1; opts.fn = oneway_diff; opts.unpack_data = revs; @@ -502,6 +503,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) memset(&opts, 0, sizeof(opts)); opts.head_idx = 1; opts.index_only = 1; + opts.diff_index_cached = 1; opts.merge = 1; opts.fn = oneway_diff; opts.unpack_data = &revs; diff --git a/unpack-trees.c b/unpack-trees.c index aaacaf1015..8eb3ddb392 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -326,6 +326,23 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str if (src[0]) conflicts |= 1; } + + /* special case: "diff-index --cached" looking at a tree */ + if (o->diff_index_cached && + n == 1 && dirmask == 1 && S_ISDIR(names->mode)) { + int matches; + matches = cache_tree_matches_traversal(o->src_index->cache_tree, + names, info); + /* + * Everything under the name matches. Adjust o->pos to + * skip the entire hierarchy. + */ + if (matches) { + o->pos += matches; + return mask; + } + } + if (traverse_trees_recursive(n, dirmask, conflicts, names, info) < 0) return -1; diff --git a/unpack-trees.h b/unpack-trees.h index 0d26f3d73e..1e0e2325f1 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -27,6 +27,7 @@ struct unpack_trees_options { aggressive:1, skip_unmerged:1, initial_checkout:1, + diff_index_cached:1, gently:1; const char *prefix; int pos; -- cgit v1.3 From a0919ced8a5efe938cf97c74a0f851cbbe00aaf6 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 22 May 2009 23:14:25 -0700 Subject: Avoid "diff-index --cached" optimization under --find-copies-harder When find-copies-harder is in effect, the diff frontends are expected to feed all paths, not just changed paths, to the diffcore, so that copy sources can be picked up. In such a case, not descending into subtrees using the cache-tree information is simply wrong. Signed-off-by: Junio C Hamano --- diff-lib.c | 5 +++-- t/t4007-rename-3.sh | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'diff-lib.c') diff --git a/diff-lib.c b/diff-lib.c index 1cb97af22d..ae75eacbcc 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -446,7 +446,8 @@ int run_diff_index(struct rev_info *revs, int cached) memset(&opts, 0, sizeof(opts)); opts.head_idx = 1; opts.index_only = cached; - opts.diff_index_cached = cached; + opts.diff_index_cached = (cached && + !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER)); opts.merge = 1; opts.fn = oneway_diff; opts.unpack_data = revs; @@ -503,7 +504,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt) memset(&opts, 0, sizeof(opts)); opts.head_idx = 1; opts.index_only = 1; - opts.diff_index_cached = 1; + opts.diff_index_cached = !DIFF_OPT_TST(opt, FIND_COPIES_HARDER); opts.merge = 1; opts.fn = oneway_diff; opts.unpack_data = &revs; diff --git a/t/t4007-rename-3.sh b/t/t4007-rename-3.sh index 25e7a83659..11502b7509 100755 --- a/t/t4007-rename-3.sh +++ b/t/t4007-rename-3.sh @@ -35,6 +35,11 @@ test_expect_success 'copy detection' ' compare_diff_raw current expected ' +test_expect_success 'copy detection, cached' ' + git diff-index -C --find-copies-harder --cached $tree >current && + compare_diff_raw current expected +' + # In the tree, there is only path0/COPYING. In the cache, path0 and # path1 both have COPYING and the latter is a copy of path0/COPYING. # However when we say we care only about path1, we should just see -- cgit v1.3