Merge branch 'maint'
authorJunio C Hamano <junkio@cox.net>
Sun, 18 Feb 2007 00:16:48 +0000 (16:16 -0800)
committerJunio C Hamano <junkio@cox.net>
Sun, 18 Feb 2007 00:16:48 +0000 (16:16 -0800)
* maint:
Update draft release notes for 1.5.0.1
Convert update-index references in docs to add.
Attempt to improve git-rebase lead-in description.
Do not take mode bits from index after type change.
git-blame: prevent argument parsing segfault
Make gitk save and restore window pane position on Linux and Cygwin.
Make gitk save and restore the user set window position.
[PATCH] gitk: Use show-ref instead of ls-remote
[PATCH] Make gitk work reasonably well on Cygwin.
[PATCH] gitk - remove trailing whitespace from a few lines.
Change git repo-config to git config

38 files changed:
.gitignore
Documentation/RelNotes-1.5.1.txt [new file with mode: 0644]
Documentation/cmd-list.perl
Documentation/core-intro.txt
Documentation/core-tutorial.txt
Documentation/diff-options.txt
Documentation/diffcore.txt
Documentation/git-diff-stages.txt [deleted file]
Documentation/git-name-rev.txt
Documentation/git-resolve.txt [deleted file]
Documentation/git-rev-list.txt
Documentation/git.txt
Documentation/howto/revert-branch-rebase.txt
Documentation/user-manual.txt
Makefile
RelNotes
builtin-blame.c
builtin-branch.c
builtin-diff-stages.c [deleted file]
builtin-merge-base.c [new file with mode: 0644]
builtin-name-rev.c
builtin-reflog.c
builtin.h
commit.c
commit.h
contrib/completion/git-completion.bash
contrib/examples/git-resolve.sh [new file with mode: 0755]
diff.c
fast-import.c
git-resolve.sh [deleted file]
git.c
merge-base.c [deleted file]
revision.c
revision.h
t/t1200-tutorial.sh
templates/hooks--update
xdiff/xdiff.h
xdiff/xutils.c
index d99372afc48a96e73da49b1f0787861efaeac1ee..f15155d1b7bcb45db6a8d67eab51b535102353c1 100644 (file)
@@ -33,7 +33,6 @@ git-daemon
 git-diff
 git-diff-files
 git-diff-index
-git-diff-stages
 git-diff-tree
 git-describe
 git-fast-import
@@ -101,7 +100,6 @@ git-repo-config
 git-request-pull
 git-rerere
 git-reset
-git-resolve
 git-rev-list
 git-rev-parse
 git-revert
diff --git a/Documentation/RelNotes-1.5.1.txt b/Documentation/RelNotes-1.5.1.txt
new file mode 100644 (file)
index 0000000..1bb6cc1
--- /dev/null
@@ -0,0 +1,39 @@
+GIT v1.5.1 Release Notes
+========================
+
+Updates since v1.5.0
+--------------------
+
+* Deprecated commands and options.
+
+  - git-diff-stages and git-resolve have been removed.
+
+* New commands and options.
+
+  - "git log" and friends take --reverse.  This makes output
+    that typically goes reverse order in chronological order.
+    "git shortlog" usually lists commits in chronological order,
+    but with "--reverse", they are shown in reverse
+    chronological order.
+
+  - "git diff" learned --ignore-space-at-eol.  This is a weaker
+    form of --ignore-space-change.
+
+* Updated behaviour of existing commands.
+
+ - "git diff" outputs a trailing HT when pathnames have embedded
+   SP on +++/--- header lines, in order to help "GNU patch" to
+   parse its output.  "git apply" was already updated to accept
+   this modified output format since ce74618d (Sep 22, 2006).
+
+* Hooks
+
+ - The sample update hook to show how to send out notification
+   e-mail was updated to show only new commits that appeared in
+   the repository.  Earlier, it showed new commits that appeared
+   on the branch.
+
+--
+O=v1.5.0-20-ga44a0c9
+echo O=`git describe master`
+git shortlog --no-merges $O..
index 75f47910557ebd3e22afce527214892c4dfe15f2..a2d6268e2b4b099b0b080d381ada189ffda592fa 100755 (executable)
@@ -90,7 +90,6 @@ sub format_one {
 git-diff-files                          plumbinginterrogators
 git-diff-index                          plumbinginterrogators
 git-diff                                mainporcelain
-git-diff-stages                         plumbinginterrogators
 git-diff-tree                           plumbinginterrogators
 git-fast-import                                ancillarymanipulators
 git-fetch                               mainporcelain
@@ -150,7 +149,6 @@ sub format_one {
 git-request-pull                        foreignscminterface
 git-rerere                              ancillaryinterrogators
 git-reset                               mainporcelain
-git-resolve                             mainporcelain
 git-revert                              mainporcelain
 git-rev-list                            plumbinginterrogators
 git-rev-parse                           ancillaryinterrogators
index 6bee448e7dea76ea58c6e2cb67f2cf507579b5f1..eea44d9d5613f448b8c2b8f0aae236f917efad39 100644 (file)
@@ -588,4 +588,5 @@ stages to temporary files and calls a "merge" script on it:
 
        git-merge-index git-merge-one-file hello.c
 
-and that is what higher level `git resolve` is implemented with.
+and that is what higher level `git merge -s resolve` is implemented
+with.
index 9c28bea62e5848e30137c063ca8fa91de737ca01..97cdb90cb4e5763a4d0cec1a0d01f5380b4e512f 100644 (file)
@@ -977,7 +977,7 @@ see more complex cases.
 Now, let's pretend you are the one who did all the work in
 `mybranch`, and the fruit of your hard work has finally been merged
 to the `master` branch. Let's go back to `mybranch`, and run
-resolve to get the "upstream changes" back to your branch.
+`git merge` to get the "upstream changes" back to your branch.
 
 ------------
 $ git checkout mybranch
@@ -996,7 +996,7 @@ Fast forward
 ----------------
 
 Because your branch did not contain anything more than what are
-already merged into the `master` branch, the resolve operation did
+already merged into the `master` branch, the merge operation did
 not actually do a merge. Instead, it just updated the top of
 the tree of your branch to that of the `master` branch. This is
 often called 'fast forward' merge.
@@ -1099,11 +1099,11 @@ programs, which are 'commit walkers'; they outlived their
 usefulness when git Native and SSH transports were introduced,
 and not used by `git pull` or `git push` scripts.
 
-Once you fetch from the remote repository, you `resolve` that
+Once you fetch from the remote repository, you `merge` that
 with your current branch.
 
 However -- it's such a common thing to `fetch` and then
-immediately `resolve`, that it's called `git pull`, and you can
+immediately `merge`, that it's called `git pull`, and you can
 simply do
 
 ----------------
index 019a39f2bf7253f3938d87a21a5467e37e33a2e0..d8696b7b36ff81f47214da9d7c4ec53142b97653 100644 (file)
 -a::
        Shorthand for "--text".
 
+--ignore-space-at-eol::
+       Ignore changes in white spaces at EOL.
+
 --ignore-space-change::
        Ignore changes in amount of white space.  This ignores white
        space at line end, and consider all other sequences of one or
index cb4e562004e58439a0055d9ed6a6bdab249dfcdc..34cd306bb1ee6ac73986cf3371114381b4165a0d 100644 (file)
@@ -6,8 +6,8 @@ June 2005
 Introduction
 ------------
 
-The diff commands git-diff-index, git-diff-files, git-diff-tree, and
-git-diff-stages can be told to manipulate differences they find in
+The diff commands git-diff-index, git-diff-files, and git-diff-tree
+can be told to manipulate differences they find in
 unconventional ways before showing diff(1) output.  The manipulation
 is collectively called "diffcore transformation".  This short note
 describes what they are and how to use them to produce diff outputs
@@ -30,9 +30,6 @@ files:
 
  - git-diff-tree compares contents of two "tree" objects;
 
- - git-diff-stages compares contents of blobs at two stages in an
-   unmerged index file.
-
 In all of these cases, the commands themselves compare
 corresponding paths in the two sets of files.  The result of
 comparison is passed from these commands to what is internally
diff --git a/Documentation/git-diff-stages.txt b/Documentation/git-diff-stages.txt
deleted file mode 100644 (file)
index b8f45b8..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-git-diff-stages(1)
-==================
-
-NAME
-----
-git-diff-stages - Compares two merge stages in the index
-
-
-SYNOPSIS
---------
-'git-diff-stages' [<common diff options>] <stage1> <stage2> [<path>...]
-
-DESCRIPTION
------------
-DEPRECATED and will be removed in 1.5.1.
-
-Compares the content and mode of the blobs in two stages in an
-unmerged index file.
-
-OPTIONS
--------
-include::diff-options.txt[]
-
-<stage1>,<stage2>::
-       The stage number to be compared.
-
-Output format
--------------
-include::diff-format.txt[]
-
-
-Author
-------
-Written by Junio C Hamano <junkio@cox.net>
-
-Documentation
---------------
-Documentation by Junio C Hamano.
-
-GIT
----
-Part of the gitlink:git[7] suite
index 37fbf66efb91ff74bf57d1b33b5ab95a248713cd..5b5c4c865f49d1da36fa1fbbcae96a33fd8da9a4 100644 (file)
@@ -8,7 +8,8 @@ git-name-rev - Find symbolic names for given revs
 
 SYNOPSIS
 --------
-'git-name-rev' [--tags] ( --all | --stdin | <committish>... )
+'git-name-rev' [--tags] [--refs=<pattern>]
+              ( --all | --stdin | <committish>... )
 
 DESCRIPTION
 -----------
@@ -22,6 +23,9 @@ OPTIONS
 --tags::
        Do not use branch names, but only tags to name the commits
 
+--refs=<pattern>::
+       Only use refs whose names match a given shell pattern.
+
 --all::
        List all commits reachable from all refs
 
diff --git a/Documentation/git-resolve.txt b/Documentation/git-resolve.txt
deleted file mode 100644 (file)
index 7fde665..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-git-resolve(1)
-==============
-
-NAME
-----
-git-resolve - Merge two commits
-
-
-SYNOPSIS
---------
-'git-resolve' <current> <merged> <message>
-
-DESCRIPTION
------------
-DEPRECATED and will be removed in 1.5.1.  Use `git-merge` instead.
-
-Given two commits and a merge message, merge the <merged> commit
-into <current> commit, with the commit log message <message>.
-
-When <current> is a descendant of <merged>, or <current> is an
-ancestor of <merged>, no new commit is created and the <message>
-is ignored.  The former is informally called "already up to
-date", and the latter is often called "fast forward".
-
-
-Author
-------
-Written by Linus Torvalds <torvalds@osdl.org> and
-Dan Holmsand <holmsand@gmail.com>.
-
-Documentation
---------------
-Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
-
-GIT
----
-Part of the gitlink:git[7] suite
-
index c742117595cd8ae5ab371a7ba21513a419af7996..4f145eaba47175e48dd592ffe5018be5cb4cb375 100644 (file)
@@ -27,6 +27,7 @@ SYNOPSIS
             [ \--pretty | \--header ]
             [ \--bisect ]
             [ \--merge ]
+            [ \--reverse ]
             [ \--walk-reflogs ]
             <commit>... [ \-- <paths>... ]
 
@@ -266,6 +267,10 @@ By default, the commits are shown in reverse chronological order.
        parent comes before all of its children, but otherwise things
        are still ordered in the commit timestamp order.
 
+--reverse::
+
+       Output the commits in reverse order.
+
 Object Traversal
 ~~~~~~~~~~~~~~~~
 
index c0fa0d4b17c3b430e18bbe7adce2147ff22344ca..3d8be5931cc7ade73198837bb360ba2a8c573d10 100644 (file)
@@ -35,6 +35,10 @@ ifdef::stalenotes[]
 You are reading the documentation for the latest version of git.
 Documentation for older releases are available here:
 
+* link:v1.5.0/git.html[documentation for release 1.5.0]
+
+* link:v1.5.0/RelNotes-1.5.0.txt[release notes for 1.5.0]
+
 * link:v1.4.4.4/git.html[documentation for release 1.4.4.4]
 
 * link:v1.3.3/git.html[documentation for release 1.3.3]
index d10476b56e7989d2c214a15491763e63e4b62c6b..d88ec23a97bc59f29a5f9734fc5ba0ef5a9ae6cf 100644 (file)
@@ -85,7 +85,7 @@ Fortunately I did not have to; what I have in the current branch
 
 ------------------------------------------------
 $ git checkout master
-$ git resolve master revert-c99 fast ;# this should be a fast forward
+$ git merge revert-c99 ;# this should be a fast forward
 Updating from 10d781b9caa4f71495c7b34963bef137216f86a8 to e3a693c...
  cache.h        |    8 ++++----
  commit.c       |    2 +-
@@ -95,13 +95,6 @@ Updating from 10d781b9caa4f71495c7b34963bef137216f86a8 to e3a693c...
  5 files changed, 8 insertions(+), 8 deletions(-)
 ------------------------------------------------
 
-The 'fast' in the above 'git resolve' is not a magic.  I knew this
-'resolve' would result in a fast forward merge, and if not, there is
-something very wrong (so I would do 'git reset' on the 'master' branch
-and examine the situation).  When a fast forward merge is done, the
-message parameter to 'git resolve' is discarded, because no new commit
-is created.  You could have said 'junk' or 'nothing' there as well.
-
 There is no need to redo the test at this point.  We fast forwarded
 and we know 'master' matches 'revert-c99' exactly.  In fact:
 
index c5e9ea8a428415940b04224b3ff902c609c9fc09..03736bbcd3ebfd5e1cbe6a006acb2b31411af527 100644 (file)
@@ -2755,7 +2755,7 @@ stages to temporary files and calls a "merge" script on it:
 $ git-merge-index git-merge-one-file hello.c
 -------------------------------------------------
 
-and that is what higher level `git resolve` is implemented with.
+and that is what higher level `git merge -s resolve` is implemented with.
 
 How git stores objects efficiently: pack files
 ----------------------------------------------
index dae29199655455abb4fa960ce4fb5d12ee469e9a..ebecbbd9c28390654ed9fea2ff4ebf6a5a317c70 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -172,7 +172,7 @@ SCRIPT_SH = \
        git-merge-one-file.sh git-parse-remote.sh \
        git-pull.sh git-rebase.sh \
        git-repack.sh git-request-pull.sh git-reset.sh \
-       git-resolve.sh git-revert.sh git-sh-setup.sh \
+       git-revert.sh git-sh-setup.sh \
        git-tag.sh git-verify-tag.sh \
        git-applymbox.sh git-applypatch.sh git-am.sh \
        git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
@@ -280,7 +280,6 @@ BUILTIN_OBJS = \
        builtin-diff.o \
        builtin-diff-files.o \
        builtin-diff-index.o \
-       builtin-diff-stages.o \
        builtin-diff-tree.o \
        builtin-fmt-merge-msg.o \
        builtin-for-each-ref.o \
@@ -292,6 +291,7 @@ BUILTIN_OBJS = \
        builtin-ls-tree.o \
        builtin-mailinfo.o \
        builtin-mailsplit.o \
+       builtin-merge-base.o \
        builtin-merge-file.o \
        builtin-mv.o \
        builtin-name-rev.o \
index 4571d0d1cfb5a4170dfc80e9654228acae295129..d5e055de6f26abba256cf32bed8dfb056bc6b29c 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes-1.5.0.txt
\ No newline at end of file
+Documentation/RelNotes-1.5.1.txt
\ No newline at end of file
index 1a752b95bb32578cd3ecb69153b55f605b8bfdc3..5669a169ff541a8ff7189ec95d907dcde248769e 100644 (file)
@@ -2065,6 +2065,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
        int i, seen_dashdash, unk, opt;
        long bottom, top, lno;
        int output_option = 0;
+       int show_stats = 0;
        const char *revs_file = NULL;
        const char *final_commit_name = NULL;
        char type[10];
@@ -2086,6 +2087,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
                        blank_boundary = 1;
                else if (!strcmp("--root", arg))
                        show_root = 1;
+               else if (!strcmp(arg, "--show-stats"))
+                       show_stats = 1;
                else if (!strcmp("-c", arg))
                        output_option |= OUTPUT_ANNOTATE_COMPAT;
                else if (!strcmp("-t", arg))
@@ -2351,7 +2354,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
                ent = e;
        }
 
-       if (DEBUG) {
+       if (show_stats) {
                printf("num read blob: %d\n", num_read_blob);
                printf("num get patch: %d\n", num_get_patch);
                printf("num commits: %d\n", num_commits);
index 2d8d61b453ede72b8d0319cb192f9f06a024d8c0..d0e720936846355b1ba8937cea9c2a14e5b8856a 100644 (file)
@@ -134,7 +134,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
                 */
 
                if (!force &&
-                   !in_merge_bases(rev, head_rev)) {
+                   !in_merge_bases(rev, &head_rev, 1)) {
                        error("The branch '%s' is not a strict subset of "
                                "your current HEAD.\n"
                                "If you are sure you want to delete it, "
diff --git a/builtin-diff-stages.c b/builtin-diff-stages.c
deleted file mode 100644 (file)
index 70bb898..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2005 Junio C Hamano
- */
-
-#include "cache.h"
-#include "diff.h"
-#include "builtin.h"
-
-static struct diff_options diff_options;
-
-static const char diff_stages_usage[] =
-"git-diff-stages [<common diff options>] <stage1> <stage2> [<path>...]"
-COMMON_DIFF_OPTIONS_HELP;
-
-static void diff_stages(int stage1, int stage2, const char **pathspec)
-{
-       int i = 0;
-       while (i < active_nr) {
-               struct cache_entry *ce, *stages[4] = { NULL, };
-               struct cache_entry *one, *two;
-               const char *name;
-               int len, skip;
-
-               ce = active_cache[i];
-               skip = !ce_path_match(ce, pathspec);
-               len = ce_namelen(ce);
-               name = ce->name;
-               for (;;) {
-                       int stage = ce_stage(ce);
-                       stages[stage] = ce;
-                       if (active_nr <= ++i)
-                               break;
-                       ce = active_cache[i];
-                       if (ce_namelen(ce) != len ||
-                           memcmp(name, ce->name, len))
-                               break;
-               }
-               one = stages[stage1];
-               two = stages[stage2];
-
-               if (skip || (!one && !two))
-                       continue;
-               if (!one)
-                       diff_addremove(&diff_options, '+', ntohl(two->ce_mode),
-                                      two->sha1, name, NULL);
-               else if (!two)
-                       diff_addremove(&diff_options, '-', ntohl(one->ce_mode),
-                                      one->sha1, name, NULL);
-               else if (hashcmp(one->sha1, two->sha1) ||
-                        (one->ce_mode != two->ce_mode) ||
-                        diff_options.find_copies_harder)
-                       diff_change(&diff_options,
-                                   ntohl(one->ce_mode), ntohl(two->ce_mode),
-                                   one->sha1, two->sha1, name, NULL);
-       }
-}
-
-int cmd_diff_stages(int ac, const char **av, const char *prefix)
-{
-       int stage1, stage2;
-       const char **pathspec = NULL;
-
-       git_config(git_default_config); /* no "diff" UI options */
-       read_cache();
-       diff_setup(&diff_options);
-       while (1 < ac && av[1][0] == '-') {
-               const char *arg = av[1];
-               if (!strcmp(arg, "-r"))
-                       ; /* as usual */
-               else {
-                       int diff_opt_cnt;
-                       diff_opt_cnt = diff_opt_parse(&diff_options,
-                                                     av+1, ac-1);
-                       if (diff_opt_cnt < 0)
-                               usage(diff_stages_usage);
-                       else if (diff_opt_cnt) {
-                               av += diff_opt_cnt;
-                               ac -= diff_opt_cnt;
-                               continue;
-                       }
-                       else
-                               usage(diff_stages_usage);
-               }
-               ac--; av++;
-       }
-
-       if (!diff_options.output_format)
-               diff_options.output_format = DIFF_FORMAT_RAW;
-
-       if (ac < 3 ||
-           sscanf(av[1], "%d", &stage1) != 1 ||
-           ! (0 <= stage1 && stage1 <= 3) ||
-           sscanf(av[2], "%d", &stage2) != 1 ||
-           ! (0 <= stage2 && stage2 <= 3))
-               usage(diff_stages_usage);
-
-       av += 3; /* The rest from av[0] are for paths restriction. */
-       pathspec = get_pathspec(prefix, av);
-
-       if (diff_setup_done(&diff_options) < 0)
-               usage(diff_stages_usage);
-
-       diff_stages(stage1, stage2, pathspec);
-       diffcore_std(&diff_options);
-       diff_flush(&diff_options);
-       return 0;
-}
diff --git a/builtin-merge-base.c b/builtin-merge-base.c
new file mode 100644 (file)
index 0000000..e35d362
--- /dev/null
@@ -0,0 +1,51 @@
+#include "cache.h"
+#include "commit.h"
+
+static int show_merge_base(struct commit *rev1, struct commit *rev2, int show_all)
+{
+       struct commit_list *result = get_merge_bases(rev1, rev2, 0);
+
+       if (!result)
+               return 1;
+
+       while (result) {
+               printf("%s\n", sha1_to_hex(result->item->object.sha1));
+               if (!show_all)
+                       return 0;
+               result = result->next;
+       }
+
+       return 0;
+}
+
+static const char merge_base_usage[] =
+"git-merge-base [--all] <commit-id> <commit-id>";
+
+int cmd_merge_base(int argc, const char **argv, const char *prefix)
+{
+       struct commit *rev1, *rev2;
+       unsigned char rev1key[20], rev2key[20];
+       int show_all = 0;
+
+       git_config(git_default_config);
+
+       while (1 < argc && argv[1][0] == '-') {
+               const char *arg = argv[1];
+               if (!strcmp(arg, "-a") || !strcmp(arg, "--all"))
+                       show_all = 1;
+               else
+                       usage(merge_base_usage);
+               argc--; argv++;
+       }
+       if (argc != 3)
+               usage(merge_base_usage);
+       if (get_sha1(argv[1], rev1key))
+               die("Not a valid object name %s", argv[1]);
+       if (get_sha1(argv[2], rev2key))
+               die("Not a valid object name %s", argv[2]);
+       rev1 = lookup_commit_reference(rev1key);
+       rev2 = lookup_commit_reference(rev2key);
+       if (!rev1 || !rev2)
+               return 1;
+       return show_merge_base(rev1, rev2, show_all);
+}
index b4f15cc38ab7fa045fc5cf025ca3fd6251a01973..36f1ba6d384d963c3ef3af1c82aff360f2409995 100644 (file)
@@ -5,7 +5,7 @@
 #include "refs.h"
 
 static const char name_rev_usage[] =
-       "git-name-rev [--tags] ( --all | --stdin | committish [committish...] )\n";
+       "git-name-rev [--tags | --refs=<pattern>] ( --all | --stdin | committish [committish...] )\n";
 
 typedef struct rev_name {
        const char *tip_name;
@@ -74,13 +74,21 @@ static void name_rev(struct commit *commit,
        }
 }
 
+struct name_ref_data {
+       int tags_only;
+       const char *ref_filter;
+};
+
 static int name_ref(const char *path, const unsigned char *sha1, int flags, void *cb_data)
 {
        struct object *o = parse_object(sha1);
-       int tags_only = *(int*)cb_data;
+       struct name_ref_data *data = cb_data;
        int deref = 0;
 
-       if (tags_only && strncmp(path, "refs/tags/", 10))
+       if (data->tags_only && strncmp(path, "refs/tags/", 10))
+               return 0;
+
+       if (data->ref_filter && fnmatch(data->ref_filter, path, 0))
                return 0;
 
        while (o && o->type == OBJ_TAG) {
@@ -129,7 +137,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
 {
        struct object_array revs = { 0, 0, NULL };
        int as_is = 0, all = 0, transform_stdin = 0;
-       int tags_only = 0;
+       struct name_ref_data data = { 0, NULL };
 
        git_config(git_default_config);
 
@@ -146,7 +154,10 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
                                as_is = 1;
                                continue;
                        } else if (!strcmp(*argv, "--tags")) {
-                               tags_only = 1;
+                               data.tags_only = 1;
+                               continue;
+                       } else  if (!strncmp(*argv, "--refs=", 7)) {
+                               data.ref_filter = *argv + 7;
                                continue;
                        } else if (!strcmp(*argv, "--all")) {
                                if (argc > 1)
@@ -185,7 +196,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
                add_object_array((struct object *)commit, *argv, &revs);
        }
 
-       for_each_ref(name_ref, &tags_only);
+       for_each_ref(name_ref, &data);
 
        if (transform_stdin) {
                char buffer[2048];
index 65b845b447b745eecd2a45e47a5c2226588dcfd1..341555139e8aca04cbc9167edf7516ab8c02c152 100644 (file)
@@ -215,8 +215,8 @@ static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
                        old = lookup_commit_reference_gently(osha1, 1);
                if (!new && !is_null_sha1(nsha1))
                        new = lookup_commit_reference_gently(nsha1, 1);
-               if ((old && !in_merge_bases(old, cb->ref_commit)) ||
-                   (new && !in_merge_bases(new, cb->ref_commit)))
+               if ((old && !in_merge_bases(old, &cb->ref_commit, 1)) ||
+                   (new && !in_merge_bases(new, &cb->ref_commit, 1)))
                        goto prune;
        }
 
index 5108fd2d74588047316b450c88f9a3f565074c30..57e8741ff0569a349a48e386fae2664fe474a546 100644 (file)
--- a/builtin.h
+++ b/builtin.h
@@ -29,7 +29,6 @@ extern int cmd_describe(int argc, const char **argv, const char *prefix);
 extern int cmd_diff_files(int argc, const char **argv, const char *prefix);
 extern int cmd_diff_index(int argc, const char **argv, const char *prefix);
 extern int cmd_diff(int argc, const char **argv, const char *prefix);
-extern int cmd_diff_stages(int argc, const char **argv, const char *prefix);
 extern int cmd_diff_tree(int argc, const char **argv, const char *prefix);
 extern int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix);
 extern int cmd_for_each_ref(int argc, const char **argv, const char *prefix);
@@ -45,6 +44,7 @@ extern int cmd_ls_files(int argc, const char **argv, const char *prefix);
 extern int cmd_ls_tree(int argc, const char **argv, const char *prefix);
 extern int cmd_mailinfo(int argc, const char **argv, const char *prefix);
 extern int cmd_mailsplit(int argc, const char **argv, const char *prefix);
+extern int cmd_merge_base(int argc, const char **argv, const char *prefix);
 extern int cmd_merge_file(int argc, const char **argv, const char *prefix);
 extern int cmd_mv(int argc, const char **argv, const char *prefix);
 extern int cmd_name_rev(int argc, const char **argv, const char *prefix);
index 3e8c87294bc9e0cdbab40d485f75e3980ae4ff10..8d279b0b635f58482b5a45c6a8a0086744b0735d 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -1187,14 +1187,17 @@ struct commit_list *get_merge_bases(struct commit *one,
        return result;
 }
 
-int in_merge_bases(struct commit *rev1, struct commit *rev2)
+int in_merge_bases(struct commit *commit, struct commit **reference, int num)
 {
        struct commit_list *bases, *b;
        int ret = 0;
 
-       bases = get_merge_bases(rev1, rev2, 1);
+       if (num == 1)
+               bases = get_merge_bases(commit, *reference, 1);
+       else
+               die("not yet");
        for (b = bases; b; b = b->next) {
-               if (!hashcmp(rev1->object.sha1, b->item->object.sha1)) {
+               if (!hashcmp(commit->object.sha1, b->item->object.sha1)) {
                        ret = 1;
                        break;
                }
index 491b0c4aac8f9690dc836a88ceda8e642c97be70..c73744463ca55ce0df3623dffbb994bd4a86d76e 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -114,5 +114,5 @@ extern int is_repository_shallow(void);
 extern struct commit_list *get_shallow_commits(struct object_array *heads,
                int depth, int shallow_flag, int not_shallow_flag);
 
-int in_merge_bases(struct commit *rev1, struct commit *rev2);
+int in_merge_bases(struct commit *, struct commit **, int);
 #endif /* COMMIT_H */
index 5d3d4020515875b7fcfae98ef03680d076d6e0ee..7c03403484f3a52c9588aa3bfc58dea4f394dabe 100755 (executable)
@@ -269,7 +269,6 @@ __git_commands ()
                cvsimport)        : import;;
                cvsserver)        : daemon;;
                daemon)           : daemon;;
-               diff-stages)      : nobody uses it;;
                fast-import)      : import;;
                fsck-objects)     : plumbing;;
                fetch-pack)       : plumbing;;
@@ -298,7 +297,6 @@ __git_commands ()
                reflog)           : plumbing;;
                repo-config)      : plumbing;;
                rerere)           : plumbing;;
-               resolve)          : dead dont use;;
                rev-list)         : plumbing;;
                rev-parse)        : plumbing;;
                runstatus)        : plumbing;;
diff --git a/contrib/examples/git-resolve.sh b/contrib/examples/git-resolve.sh
new file mode 100755 (executable)
index 0000000..36b90e3
--- /dev/null
@@ -0,0 +1,112 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Linus Torvalds
+#
+# Resolve two trees.
+#
+
+echo 'WARNING: This command is DEPRECATED and will be removed very soon.' >&2
+echo 'WARNING: Please use git-merge or git-pull instead.' >&2
+sleep 2
+
+USAGE='<head> <remote> <merge-message>'
+. git-sh-setup
+
+dropheads() {
+       rm -f -- "$GIT_DIR/MERGE_HEAD" \
+               "$GIT_DIR/LAST_MERGE" || exit 1
+}
+
+head=$(git-rev-parse --verify "$1"^0) &&
+merge=$(git-rev-parse --verify "$2"^0) &&
+merge_name="$2" &&
+merge_msg="$3" || usage
+
+#
+# The remote name is just used for the message,
+# but we do want it.
+#
+if [ -z "$head" -o -z "$merge" -o -z "$merge_msg" ]; then
+       usage
+fi
+
+dropheads
+echo $head > "$GIT_DIR"/ORIG_HEAD
+echo $merge > "$GIT_DIR"/LAST_MERGE
+
+common=$(git-merge-base $head $merge)
+if [ -z "$common" ]; then
+       die "Unable to find common commit between" $merge $head
+fi
+
+case "$common" in
+"$merge")
+       echo "Already up-to-date. Yeeah!"
+       dropheads
+       exit 0
+       ;;
+"$head")
+       echo "Updating $(git-rev-parse --short $head)..$(git-rev-parse --short $merge)"
+       git-read-tree -u -m $head $merge || exit 1
+       git-update-ref -m "resolve $merge_name: Fast forward" \
+               HEAD "$merge" "$head"
+       git-diff-tree -p $head $merge | git-apply --stat
+       dropheads
+       exit 0
+       ;;
+esac
+
+# We are going to make a new commit.
+git var GIT_COMMITTER_IDENT >/dev/null || exit
+
+# Find an optimum merge base if there are more than one candidates.
+LF='
+'
+common=$(git-merge-base -a $head $merge)
+case "$common" in
+?*"$LF"?*)
+       echo "Trying to find the optimum merge base."
+       G=.tmp-index$$
+       best=
+       best_cnt=-1
+       for c in $common
+       do
+               rm -f $G
+               GIT_INDEX_FILE=$G git-read-tree -m $c $head $merge \
+                       2>/dev/null || continue
+               # Count the paths that are unmerged.
+               cnt=`GIT_INDEX_FILE=$G git-ls-files --unmerged | wc -l`
+               if test $best_cnt -le 0 -o $cnt -le $best_cnt
+               then
+                       best=$c
+                       best_cnt=$cnt
+                       if test "$best_cnt" -eq 0
+                       then
+                               # Cannot do any better than all trivial merge.
+                               break
+                       fi
+               fi
+       done
+       rm -f $G
+       common="$best"
+esac
+
+echo "Trying to merge $merge into $head using $common."
+git-update-index --refresh 2>/dev/null
+git-read-tree -u -m $common $head $merge || exit 1
+result_tree=$(git-write-tree  2> /dev/null)
+if [ $? -ne 0 ]; then
+       echo "Simple merge failed, trying Automatic merge"
+       git-merge-index -o git-merge-one-file -a
+       if [ $? -ne 0 ]; then
+               echo $merge > "$GIT_DIR"/MERGE_HEAD
+               die "Automatic merge failed, fix up by hand"
+       fi
+       result_tree=$(git-write-tree) || exit 1
+fi
+result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p $merge)
+echo "Committed merge $result_commit"
+git-update-ref -m "resolve $merge_name: In-index merge" \
+       HEAD "$result_commit" "$head"
+git-diff-tree -p $head $result_commit | git-apply --stat
+dropheads
diff --git a/diff.c b/diff.c
index 13b9b6c5602cc1aca4a95ed4d292756d3380c543..12c8b2b876fc09454204cac3d26a0e98413bfbe2 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -207,11 +207,18 @@ static void emit_rewrite_diff(const char *name_a,
                              struct diff_filespec *two)
 {
        int lc_a, lc_b;
+       const char *name_a_tab, *name_b_tab;
+
+       name_a_tab = strchr(name_a, ' ') ? "\t" : "";
+       name_b_tab = strchr(name_b, ' ') ? "\t" : "";
+
        diff_populate_filespec(one, 0);
        diff_populate_filespec(two, 0);
        lc_a = count_lines(one->data, one->size);
        lc_b = count_lines(two->data, two->size);
-       printf("--- a/%s\n+++ b/%s\n@@ -", name_a, name_b);
+       printf("--- a/%s%s\n+++ b/%s%s\n@@ -",
+              name_a, name_a_tab,
+              name_b, name_b_tab);
        print_line_count(lc_a);
        printf(" +");
        print_line_count(lc_b);
@@ -477,8 +484,15 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
        const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET);
 
        if (ecbdata->label_path[0]) {
-               printf("%s--- %s%s\n", set, ecbdata->label_path[0], reset);
-               printf("%s+++ %s%s\n", set, ecbdata->label_path[1], reset);
+               const char *name_a_tab, *name_b_tab;
+
+               name_a_tab = strchr(ecbdata->label_path[0], ' ') ? "\t" : "";
+               name_b_tab = strchr(ecbdata->label_path[1], ' ') ? "\t" : "";
+
+               printf("%s--- %s%s%s\n",
+                      set, ecbdata->label_path[0], reset, name_a_tab);
+               printf("%s+++ %s%s%s\n",
+                      set, ecbdata->label_path[1], reset, name_b_tab);
                ecbdata->label_path[0] = ecbdata->label_path[1] = NULL;
        }
 
@@ -2024,6 +2038,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
                options->xdl_opts |= XDF_IGNORE_WHITESPACE;
        else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change"))
                options->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
+       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;
        else if (!strcmp(arg, "--no-renames"))
index fd3b11757498d504b3954f70c602603d65277440..404d911390bdb4700d0ee0df46bd7849c1890016 100644 (file)
@@ -1308,7 +1308,7 @@ static int update_branch(struct branch *b)
                        return error("Branch %s is missing commits.", b->name);
                }
 
-               if (!in_merge_bases(old_cmit, new_cmit)) {
+               if (!in_merge_bases(old_cmit, &new_cmit, 1)) {
                        unlock_ref(lock);
                        warn("Not updating %s"
                                " (new tip %s does not contain %s)",
diff --git a/git-resolve.sh b/git-resolve.sh
deleted file mode 100755 (executable)
index 36b90e3..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-#
-# Resolve two trees.
-#
-
-echo 'WARNING: This command is DEPRECATED and will be removed very soon.' >&2
-echo 'WARNING: Please use git-merge or git-pull instead.' >&2
-sleep 2
-
-USAGE='<head> <remote> <merge-message>'
-. git-sh-setup
-
-dropheads() {
-       rm -f -- "$GIT_DIR/MERGE_HEAD" \
-               "$GIT_DIR/LAST_MERGE" || exit 1
-}
-
-head=$(git-rev-parse --verify "$1"^0) &&
-merge=$(git-rev-parse --verify "$2"^0) &&
-merge_name="$2" &&
-merge_msg="$3" || usage
-
-#
-# The remote name is just used for the message,
-# but we do want it.
-#
-if [ -z "$head" -o -z "$merge" -o -z "$merge_msg" ]; then
-       usage
-fi
-
-dropheads
-echo $head > "$GIT_DIR"/ORIG_HEAD
-echo $merge > "$GIT_DIR"/LAST_MERGE
-
-common=$(git-merge-base $head $merge)
-if [ -z "$common" ]; then
-       die "Unable to find common commit between" $merge $head
-fi
-
-case "$common" in
-"$merge")
-       echo "Already up-to-date. Yeeah!"
-       dropheads
-       exit 0
-       ;;
-"$head")
-       echo "Updating $(git-rev-parse --short $head)..$(git-rev-parse --short $merge)"
-       git-read-tree -u -m $head $merge || exit 1
-       git-update-ref -m "resolve $merge_name: Fast forward" \
-               HEAD "$merge" "$head"
-       git-diff-tree -p $head $merge | git-apply --stat
-       dropheads
-       exit 0
-       ;;
-esac
-
-# We are going to make a new commit.
-git var GIT_COMMITTER_IDENT >/dev/null || exit
-
-# Find an optimum merge base if there are more than one candidates.
-LF='
-'
-common=$(git-merge-base -a $head $merge)
-case "$common" in
-?*"$LF"?*)
-       echo "Trying to find the optimum merge base."
-       G=.tmp-index$$
-       best=
-       best_cnt=-1
-       for c in $common
-       do
-               rm -f $G
-               GIT_INDEX_FILE=$G git-read-tree -m $c $head $merge \
-                       2>/dev/null || continue
-               # Count the paths that are unmerged.
-               cnt=`GIT_INDEX_FILE=$G git-ls-files --unmerged | wc -l`
-               if test $best_cnt -le 0 -o $cnt -le $best_cnt
-               then
-                       best=$c
-                       best_cnt=$cnt
-                       if test "$best_cnt" -eq 0
-                       then
-                               # Cannot do any better than all trivial merge.
-                               break
-                       fi
-               fi
-       done
-       rm -f $G
-       common="$best"
-esac
-
-echo "Trying to merge $merge into $head using $common."
-git-update-index --refresh 2>/dev/null
-git-read-tree -u -m $common $head $merge || exit 1
-result_tree=$(git-write-tree  2> /dev/null)
-if [ $? -ne 0 ]; then
-       echo "Simple merge failed, trying Automatic merge"
-       git-merge-index -o git-merge-one-file -a
-       if [ $? -ne 0 ]; then
-               echo $merge > "$GIT_DIR"/MERGE_HEAD
-               die "Automatic merge failed, fix up by hand"
-       fi
-       result_tree=$(git-write-tree) || exit 1
-fi
-result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p $merge)
-echo "Committed merge $result_commit"
-git-update-ref -m "resolve $merge_name: In-index merge" \
-       HEAD "$result_commit" "$head"
-git-diff-tree -p $head $result_commit | git-apply --stat
-dropheads
diff --git a/git.c b/git.c
index 45265f14d0cc225dedcae84b7e2ef5700b966f20..4dd196721f552579c6cd5ec75275b869c72e5118 100644 (file)
--- a/git.c
+++ b/git.c
@@ -240,7 +240,6 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
                { "diff", cmd_diff, RUN_SETUP | USE_PAGER },
                { "diff-files", cmd_diff_files, RUN_SETUP },
                { "diff-index", cmd_diff_index, RUN_SETUP },
-               { "diff-stages", cmd_diff_stages, RUN_SETUP },
                { "diff-tree", cmd_diff_tree, RUN_SETUP },
                { "fmt-merge-msg", cmd_fmt_merge_msg, RUN_SETUP },
                { "for-each-ref", cmd_for_each_ref, RUN_SETUP },
@@ -257,6 +256,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
                { "ls-tree", cmd_ls_tree, RUN_SETUP },
                { "mailinfo", cmd_mailinfo },
                { "mailsplit", cmd_mailsplit },
+               { "merge-base", cmd_merge_base, RUN_SETUP },
                { "merge-file", cmd_merge_file },
                { "mv", cmd_mv, RUN_SETUP | NOT_BARE },
                { "name-rev", cmd_name_rev, RUN_SETUP },
diff --git a/merge-base.c b/merge-base.c
deleted file mode 100644 (file)
index 385f4ba..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#include "cache.h"
-#include "commit.h"
-
-static int show_all;
-
-static int merge_base(struct commit *rev1, struct commit *rev2)
-{
-       struct commit_list *result = get_merge_bases(rev1, rev2, 0);
-
-       if (!result)
-               return 1;
-
-       while (result) {
-               printf("%s\n", sha1_to_hex(result->item->object.sha1));
-               if (!show_all)
-                       return 0;
-               result = result->next;
-       }
-
-       return 0;
-}
-
-static const char merge_base_usage[] =
-"git-merge-base [--all] <commit-id> <commit-id>";
-
-int main(int argc, char **argv)
-{
-       struct commit *rev1, *rev2;
-       unsigned char rev1key[20], rev2key[20];
-
-       setup_git_directory();
-       git_config(git_default_config);
-
-       while (1 < argc && argv[1][0] == '-') {
-               char *arg = argv[1];
-               if (!strcmp(arg, "-a") || !strcmp(arg, "--all"))
-                       show_all = 1;
-               else
-                       usage(merge_base_usage);
-               argc--; argv++;
-       }
-       if (argc != 3)
-               usage(merge_base_usage);
-       if (get_sha1(argv[1], rev1key))
-               die("Not a valid object name %s", argv[1]);
-       if (get_sha1(argv[2], rev2key))
-               die("Not a valid object name %s", argv[2]);
-       rev1 = lookup_commit_reference(rev1key);
-       rev2 = lookup_commit_reference(rev2key);
-       if (!rev1 || !rev2)
-               return 1;
-       return merge_base(rev1, rev2);
-}
index 15bdaf6095ccbe690c664f80a5b25e354d068d61..5b1794b0efbd628f935db006835168ea3e640de4 100644 (file)
@@ -1058,6 +1058,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                                        git_log_output_encoding = "";
                                continue;
                        }
+                       if (!strcmp(arg, "--reverse")) {
+                               revs->reverse ^= 1;
+                               continue;
+                       }
 
                        opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);
                        if (opts > 0) {
@@ -1286,6 +1290,40 @@ struct commit *get_revision(struct rev_info *revs)
 {
        struct commit *c = NULL;
 
+       if (revs->reverse) {
+               struct commit_list *list;
+
+               /*
+                * rev_info.reverse is used to note the fact that we
+                * want to output the list of revisions in reverse
+                * order.  To accomplish this goal, reverse can have
+                * different values:
+                *
+                *  0  do nothing
+                *  1  reverse the list
+                *  2  internal use:  we have already obtained and
+                *     reversed the list, now we only need to yield
+                *     its items.
+                */
+
+               if (revs->reverse == 1) {
+                       revs->reverse = 0;
+                       list = NULL;
+                       while ((c = get_revision(revs)))
+                               commit_list_insert(c, &list);
+                       revs->commits = list;
+                       revs->reverse = 2;
+               }
+
+               if (!revs->commits)
+                       return NULL;
+               c = revs->commits->item;
+               list = revs->commits->next;
+               free(revs->commits);
+               revs->commits = list;
+               return c;
+       }
+
        if (0 < revs->skip_count) {
                while ((c = get_revision_1(revs)) != NULL) {
                        if (revs->skip_count-- <= 0)
index d93481f68f53a657fe4b174e4a12777efe6a74bb..5fec1846f366f1aadabc6f57edcfd17828afa8ee 100644 (file)
@@ -42,7 +42,8 @@ struct rev_info {
                        unpacked:1, /* see also ignore_packed below */
                        boundary:1,
                        left_right:1,
-                       parents:1;
+                       parents:1,
+                       reverse:2;
 
        /* Diff flags */
        unsigned int    diff:1,
index eebe643bda9dd5180e8435a59c7510ba97e59144..ca2c30f7aff5beda97ea598e272750c23e34296e 100755 (executable)
@@ -101,7 +101,9 @@ echo "Play, play, play" >>hello
 echo "Lots of fun" >>example
 git commit -m 'Some fun.' -i hello example
 
-test_expect_failure 'git resolve now fails' 'git resolve HEAD mybranch "Merge work in mybranch"'
+test_expect_failure 'git resolve now fails' '
+       git merge -m "Merge work in mybranch" mybranch
+'
 
 cat > hello << EOF
 Hello World
@@ -134,8 +136,8 @@ Updating from VARIABLE to VARIABLE
  2 files changed, 2 insertions(+), 0 deletions(-)
 EOF
 
-git resolve HEAD master "Merge upstream changes." | \
-       sed -e "1s/[0-9a-f]\{40\}/VARIABLE/g" > resolve.output
+git merge -s "Merge upstream changes." master | \
+       sed -e "1s/[0-9a-f]\{40\}/VARIABLE/g" >resolve.output
 test_expect_success 'git resolve' 'cmp resolve.expect resolve.output'
 
 cat > show-branch2.expect << EOF
index e8c536fb616d9fe93fe50edf4bc862b58ad6af1b..fd1f73d6aa48b104cc74d08dcb6a29bd3f8f08d9 100644 (file)
@@ -57,7 +57,7 @@ announcerecipients=$(git-repo-config hooks.announcelist)
 allowunannotated=$(git-repo-config --bool hooks.allowunannotated)
 
 # --- Check types
-newrev_type=$(git-cat-file -t "$newrev")
+newrev_type=$(git-cat-file -t $newrev)
 
 case "$refname","$newrev_type" in
        refs/tags/*,commit)
@@ -165,7 +165,7 @@ case "$refname_type" in
                        baserev=$(git-merge-base $oldrev $newrev)
 
                        # Commit with a parent
-                       for rev in $(git-rev-list $newrev ^$baserev)
+                       for rev in $(git-rev-parse --not --all | git-rev-list --stdin $newrev ^$baserev)
                        do
                                revtype=$(git-cat-file -t "$rev")
                                echo "       via  $rev ($revtype)"
@@ -190,7 +190,8 @@ case "$refname_type" in
                        fi
                        echo ""
                        echo $LOGBEGIN
-                       git-rev-list --pretty $newrev ^$baserev
+                       git-rev-parse --not --all |
+                       git-rev-list --stdin --pretty $newrev ^$baserev
                        echo $LOGEND
                        echo ""
                        echo "Diffstat:"
index fa409d5234009bf6ddac8803e8d20ed1b23a3258..e874a7c46a90104ebf586d0fc48964634f356763 100644 (file)
@@ -31,7 +31,8 @@ extern "C" {
 #define XDF_NEED_MINIMAL (1 << 1)
 #define XDF_IGNORE_WHITESPACE (1 << 2)
 #define XDF_IGNORE_WHITESPACE_CHANGE (1 << 3)
-#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE)
+#define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 4)
+#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_WHITESPACE_AT_EOL)
 
 #define XDL_PATCH_NORMAL '-'
 #define XDL_PATCH_REVERSE '+'
index 1b899f32c4b7c3f00c5310a161d0d9afd459f002..3653864e4bf704c024453df8d9abf26d89b4778d 100644 (file)
@@ -215,6 +215,21 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
                                return 0;
                }
                return (i1 >= s1 && i2 >= s2);
+       } else if (flags & XDF_IGNORE_WHITESPACE_AT_EOL) {
+               for (i1 = i2 = 0; i1 < s1 && i2 < s2; ) {
+                       if (l1[i1] != l2[i2]) {
+                               while (i1 < s1 && isspace(l1[i1]))
+                                       i1++;
+                               while (i2 < s2 && isspace(l2[i2]))
+                                       i2++;
+                               if (i1 < s1 || i2 < s2)
+                                       return 0;
+                               return 1;
+                       }
+                       i1++;
+                       i2++;
+               }
+               return i1 >= s1 && i2 >= s2;
        } else
                return s1 == s2 && !memcmp(l1, l2, s1);
 
@@ -227,6 +242,7 @@ unsigned long xdl_hash_record(char const **data, char const *top, long flags) {
 
        for (; ptr < top && *ptr != '\n'; ptr++) {
                if (isspace(*ptr) && (flags & XDF_WHITESPACE_FLAGS)) {
+                       const char *ptr2 = ptr;
                        while (ptr + 1 < top && isspace(ptr[1])
                                        && ptr[1] != '\n')
                                ptr++;
@@ -235,6 +251,14 @@ unsigned long xdl_hash_record(char const **data, char const *top, long flags) {
                                ha += (ha << 5);
                                ha ^= (unsigned long) ' ';
                        }
+                       if (flags & XDF_IGNORE_WHITESPACE_AT_EOL
+                                       && ptr[1] != '\n') {
+                               while (ptr2 != ptr + 1) {
+                                       ha += (ha << 5);
+                                       ha ^= (unsigned long) *ptr2;
+                                       ptr2++;
+                               }
+                       }
                        continue;
                }
                ha += (ha << 5);