Evil Merge branch 'jc/status' (early part) into js/diff-ni
authorJunio C Hamano <junkio@cox.net>
Sat, 24 Feb 2007 10:20:13 +0000 (02:20 -0800)
committerJunio C Hamano <junkio@cox.net>
Sat, 24 Feb 2007 10:20:13 +0000 (02:20 -0800)
* 'jc/status' (early part):
run_diff_{files,index}(): update calling convention.
update-index: do not die too early in a read-only repository.
git-status: do not be totally useless in a read-only repository.

This is to resolve semantic conflict (which is not textual) that
changes the calling convention of run_diff_files() early.

68 files changed:
.gitignore
Documentation/RelNotes-1.5.0.1.txt [new file with mode: 0644]
Documentation/RelNotes-1.5.0.txt
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-checkout.txt
Documentation/git-diff-files.txt
Documentation/git-diff-stages.txt [deleted file]
Documentation/git-diff.txt
Documentation/git-fast-import.txt
Documentation/git-merge.txt
Documentation/git-name-rev.txt
Documentation/git-rebase.txt
Documentation/git-rerere.txt
Documentation/git-reset.txt
Documentation/git-resolve.txt [deleted file]
Documentation/git-rev-list.txt
Documentation/git-runstatus.txt
Documentation/git-status.txt
Documentation/git.txt
Documentation/howto/revert-branch-rebase.txt
Documentation/i18n.txt
Documentation/tutorial-2.txt
Documentation/user-manual.txt
GIT-VERSION-GEN
Makefile
RelNotes
builtin-apply.c
builtin-blame.c
builtin-branch.c
builtin-diff-files.c
builtin-diff-stages.c [deleted file]
builtin-diff.c
builtin-merge-base.c [new file with mode: 0644]
builtin-name-rev.c
builtin-reflog.c
builtin-rev-list.c
builtin-update-index.c
builtin.h
cache.h
commit.c
commit.h
config.c
contrib/completion/git-completion.bash
contrib/examples/git-resolve.sh [new file with mode: 0755]
daemon.c
diff-lib.c
diff.c
diff.h
fast-import.c
git-compat-util.h
git-merge.sh
git-resolve.sh [deleted file]
git.c
merge-base.c [deleted file]
read-cache.c
revision.c
revision.h
sha1_file.c
t/t1200-tutorial.sh
t/t3700-add.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.0.1.txt b/Documentation/RelNotes-1.5.0.1.txt
new file mode 100644 (file)
index 0000000..fea3f99
--- /dev/null
@@ -0,0 +1,42 @@
+GIT v1.5.0.1 Release Notes
+==========================
+
+Fixes since v1.5.0
+------------------
+
+* Documentation updates
+
+  - Clarifications and corrections to 1.5.0 release notes.
+
+  - The main documentation did not link to git-remote documentation.
+
+  - Clarified introductory text of git-rebase documentation.
+
+  - Converted remaining mentions of update-index on Porcelain
+    documents to git-add/git-rm.
+
+  - Some i18n.* configuration variables were incorrectly
+    described as core.*; fixed.
+
+* Bugfixes
+
+  - git-add and git-update-index on a filesystem on which
+    executable bits are unreliable incorrectly reused st_mode
+    bits even when the path changed between symlink and regular
+    file.
+
+  - git-daemon marks the listening sockets with FD_CLOEXEC so
+    that it won't be leaked into the children.
+
+  - segfault from git-blame when the mandatory pathname
+    parameter was missing was fixed; usage() message is given
+    instead.
+
+  - git-rev-list did not read $GIT_DIR/config file, which means
+    that did not honor i18n.logoutputencoding correctly.
+
+* Tweaks
+
+  - sliding mmap() inefficiently mmaped the same region of a
+    packfile with an access pattern that used objects in the
+    reverse order.  This has been made more efficient.
index 84e7eaf3c879213b2d3ab169217f93f5c3154882..599efb8c908d96e4de938458654cbbe907cf00bb 100644 (file)
@@ -25,12 +25,18 @@ Specifically, the available options are:
    older clients over dumb transports (e.g. http) using older
    versions of git will also be affected.
 
+   To let git use the new loose object format, you have to
+   set core.legacyheaders to false.
+
  - Since v1.4.3, configuration repack.usedeltabaseoffset allows
    packfile to be created in more space efficient format, which
    cannot be read by git older than that version.
 
-The above two are not enabled by default and you explicitly have
-to ask for them, because these two features make repositories
+   To let git use the new format for packfiles, you have to
+   set repack.usedeltabaseoffset to true.
+
+The above two new features are not enabled by default and you
+have to explicitly ask for them, because they make repositories
 unreadable by older versions of git, and in v1.5.0 we still do
 not enable them by default for the same reason.  We will change
 this default probably 1 year after 1.4.2's release, when it is
@@ -94,8 +100,8 @@ Updates in v1.5.0 since v1.4.4 series
    entries for selected paths.
 
  - git-update-index is much less visible.  Many suggestions to
-  use the command in git output and documentation have now been
-  replaced by simpler commands such as "git add" or "git rm".
+   use the command in git output and documentation have now been
+   replaced by simpler commands such as "git add" or "git rm".
 
 
 * Repository layout and objects transfer
@@ -217,7 +223,7 @@ Updates in v1.5.0 since v1.4.4 series
    "branch@{Nth}" notation.
 
  - "git show-branch" learned showing the reflog data with the
-   new -g option.  "git log" has -s option to view reflog
+   new -g option.  "git log" has -g option to view reflog
    entries in a more verbose manner.
 
  - git-branch knows how to rename branches and moves existing
@@ -253,9 +259,6 @@ Updates in v1.5.0 since v1.4.4 series
    above sentence, as git-prune does not remove things reachable
    from reflog entries.
 
- - 'git-prune' by default does not remove _everything_
-   unreachable, as there is a one-day grace period built-in.
-
  - There is a toplevel garbage collector script, 'git-gc', that
    runs periodic cleanup functions, including 'git-repack -a -d',
    'git-reflog expire', 'git-pack-refs --prune', and 'git-rerere
@@ -291,12 +294,10 @@ Updates in v1.5.0 since v1.4.4 series
    reset" to jump to arbitrary commit, while still keeping your
    HEAD detached.
 
-   Going back to attached state (i.e. on a particular branch) by
-   "git checkout $branch" can lose the current stat you arrived
-   in these ways, and "git checkout" refuses when the detached
-   HEAD is not pointed by any existing ref (an existing branch,
-   a remote tracking branch or a tag).  This safety can be
-   overridden with "git checkout -f $branch".
+   Remember that a detached state is volatile, i.e. it will be forgotten
+   as soon as you move away from it with the checkout or reset command,
+   unless a branch is created from it as mentioned above.  It is also
+   possible to rescue a lost detached state from the HEAD reflog.
 
 
 * Packed refs
@@ -411,14 +412,14 @@ Updates in v1.5.0 since v1.4.4 series
 
 * Foreign SCM interfaces
 
 - git-svn now requires the Perl SVN:: libraries, the
-    command-line backend was too slow and limited.
+ - git-svn now requires the Perl SVN:: libraries, the
+   command-line backend was too slow and limited.
 
 - the 'commit' subcommand of git-svn has been renamed to
-    'set-tree', and 'dcommit' is the recommended replacement for
-    day-to-day work.
+ - the 'commit' subcommand of git-svn has been renamed to
+   'set-tree', and 'dcommit' is the recommended replacement for
+   day-to-day work.
 
 - git fast-import backend.
+ - git fast-import backend.
 
 
 * User support
diff --git a/Documentation/RelNotes-1.5.1.txt b/Documentation/RelNotes-1.5.1.txt
new file mode 100644 (file)
index 0000000..4d37186
--- /dev/null
@@ -0,0 +1,44 @@
+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.
+
+  - "git name-rev" learned --refs=<pattern>, to limit the tags
+    used for naming the given revisions only to the ones
+    matching the given pattern.
+
+* 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.
+
+--
+exec >/var/tmp/1
+O=v1.5.0-49-g69bc0e2
+echo O=`git describe master`
+git shortlog --no-merges $O..master ^maint
index 69003e90af222db3a7e38897930cc3af71c8d2f9..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
@@ -146,10 +145,10 @@ sub format_one {
 git-relink                              ancillarymanipulators
 git-repack                              ancillarymanipulators
 git-config                              ancillarymanipulators
+git-remote                              ancillarymanipulators
 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 abafefc71c37d8a3015f0227d24da0f07096fe4c..eea44d9d5613f448b8c2b8f0aae236f917efad39 100644 (file)
@@ -106,7 +106,8 @@ directory tree, and renaming a file does not change the object that
 file is associated with in any way.
 
 A blob is typically created when gitlink:git-update-index[1]
-is run, and its data can be accessed by gitlink:git-cat-file[1].
+(or gitlink:git-add[1]) is run, and its data can be accessed by
+gitlink:git-cat-file[1].
 
 Tree Object
 ~~~~~~~~~~~
@@ -587,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
index e4ffde4fdd78f4fe476951c9eeabebf143647eb3..1ae77be45055418b9c784d15db520841dd7bdd7a 100644 (file)
@@ -61,7 +61,8 @@ OPTIONS
 +
 When a merge conflict happens, the index entries for conflicting
 paths are left unmerged, and you need to resolve the conflicts
-and mark the resolved paths with `git update-index`.
+and mark the resolved paths with `git add` (or `git rm` if the merge
+should result in deletion of the path).
 
 <new_branch>::
        Name for the new branch.
@@ -179,11 +180,11 @@ fatal: merge program failed
 At this point, `git diff` shows the changes cleanly merged as in
 the previous example, as well as the changes in the conflicted
 files.  Edit and resolve the conflict and mark it resolved with
-`git update-index` as usual:
+`git add` as usual:
 +
 ------------
 $ edit frotz
-$ git update-index frotz
+$ git add frotz
 ------------
 
 
index 7248b35d952c3fe97496895059af35300694eb98..b78c4c64f1b2638b8be42072a0f9a4eab1362f7f 100644 (file)
@@ -8,7 +8,7 @@ git-diff-files - Compares files in the working tree and the index
 
 SYNOPSIS
 --------
-'git-diff-files' [-q] [-0|-1|-2|-3|-c|--cc] [<common diff options>] [<path>...]
+'git-diff-files' [-q] [-0|-1|-2|-3|-c|--cc|-n|--no-index] [<common diff options>] [<path>...]
 
 DESCRIPTION
 -----------
@@ -36,6 +36,9 @@ omit diff output for unmerged entries and just show "Unmerged".
        diff, similar to the way 'diff-tree' shows a merge
        commit with these flags.
 
+\-n,\--no-index::
+       Compare the two given files / directories.
+
 -q::
        Remain silent even on nonexistent files
 
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 6a098df26b1c1639f6ac88233b5642a2be9039fa..12a531d1e9e4a7382f017ac303203e20abf47f2f 100644 (file)
@@ -23,6 +23,10 @@ tree and the index file, or the index file and the working tree.
        further add to the index but you still haven't.  You can
        stage these changes by using gitlink:git-add[1].
 
+       If exactly two paths are given, and at least one is untracked,
+       compare the two files / directories. This behavior can be
+       forced by --no-index.
+
 'git-diff' [--options] --cached [<commit>] [--] [<path>...]::
 
        This form is to view the changes you staged for the next
index 445f6b854404c33b970004b791721be2986cf4bf..77a14bb076b6d8be624345ee10e4bd14cfb2c359 100644 (file)
@@ -3,7 +3,7 @@ git-fast-import(1)
 
 NAME
 ----
-git-fast-import - Backend for fast Git data importers.
+git-fast-import - Backend for fast Git data importers
 
 
 SYNOPSIS
index e53ff4b4e7464079ac6e19f2bceafcb44044fb39..9c08efa53abc2797a7b7ca0e589d83b9a4387987 100644 (file)
@@ -136,7 +136,7 @@ After seeing a conflict, you can do two things:
 
  * Resolve the conflicts.  `git-diff` would report only the
    conflicting paths because of the above 2. and 3..  Edit the
-   working tree files into a desirable shape, `git-update-index`
+   working tree files into a desirable shape, `git-add` or `git-rm`
    them, to make the index file contain what the merge result
    should be, and run `git-commit` to commit the result.
 
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
 
index f2ef1f7dc093432e8b6c5644cbac5c5e857cb0ca..2f417a8f856094b3664eeff2ff3f0ce761c89503 100644 (file)
@@ -13,11 +13,20 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-git-rebase replaces <branch> with a new branch of the same name.  When
-the --onto option is provided the new branch starts out with a HEAD equal
-to <newbase>, otherwise it is equal to <upstream>.  It then attempts to
-create a new commit for each commit from the original <branch> that does
-not exist in the <upstream> branch.
+If <branch> is specified, git-rebase will perform an automatic
+`git checkout <branch>` before doing anything else.  Otherwise
+it remains on the current branch.
+
+All changes made by commits in the current branch but that are not
+in <upstream> are saved to a temporary area.  This is the same set
+of commits that would be shown by `git log <upstream>..HEAD`.
+
+The current branch is reset to <upstream>, or <newbase> if the
+--onto option was supplied.  This has the exact same effect as
+`git reset --hard <upstream>` (or <newbase>).
+
+The commits that were previously saved into the temporary area are
+then reapplied to the current branch, one by one, in order.
 
 It is possible that a merge failure will prevent this process from being
 completely automatic.  You will have to resolve any such merge failure
@@ -26,9 +35,6 @@ that caused the merge failure with `git rebase --skip`.  To restore the
 original <branch> and remove the .dotest working files, use the command
 `git rebase --abort` instead.
 
-Note that if <branch> is not specified on the command line, the currently
-checked out branch is used.
-
 Assume the following history exists and the current branch is "topic":
 
 ------------
@@ -142,7 +148,7 @@ file you edit, you need to tell git that the conflict has been resolved,
 typically this would be done with
 
 
-    git update-index <filename>
+    git add <filename>
 
 
 After resolving the conflict manually and updating the index with the
index 139b6eb7733aaf246af8ce77f6483fa15e5de2b0..7ff9b05e680cabc6513f9d8a6aa80eb7eccda82d 100644 (file)
@@ -163,8 +163,7 @@ If this three-way merge resolves cleanly, the result is written
 out to your working tree file, so you would not have to manually
 resolve it.  Note that `git-rerere` leaves the index file alone,
 so you still need to do the final sanity checks with `git diff`
-(or `git diff -c`) and `git update-index` when you are
-satisfied.
+(or `git diff -c`) and `git add` when you are satisfied.
 
 As a convenience measure, `git-merge` automatically invokes
 `git-rerere` when it exits with a failed automerge, which
index 04475a92168feb98e0de1e386476ca702fb6c41b..5b55cda512bbdb507486ac5d0db0d28e32b1dcb1 100644 (file)
@@ -94,11 +94,11 @@ current HEAD.
 <2> Rewind the master branch to get rid of those three commits.
 <3> Switch to "topic/wip" branch and keep working.
 
-Undo update-index::
+Undo add::
 +
 ------------
 $ edit                                     <1>
-$ git-update-index frotz.c filfre.c
+$ git add frotz.c filfre.c
 $ mailx                                    <2>
 $ git reset                                <3>
 $ git pull git://info.example.com/ nitfol  <4>
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 89d7b9273107d64eb88e81e07c188e00ea1f9074..8bb52f46872194783148851ca2fe81dfb9d13bf7 100644 (file)
@@ -16,7 +16,7 @@ DESCRIPTION
 Examines paths in the working tree that has changes unrecorded
 to the index file, and changes between the index file and the
 current HEAD commit.  The former paths are what you _could_
-commit by running 'git-update-index' before running 'git
+commit by running 'git add' (or 'git rm' if you are deleting) before running 'git
 commit', and the latter paths are what you _would_ commit by
 running 'git commit'.
 
index 03871e5d734dc295bba92e965721f6aa4142172f..e9e193f00866f97b341eebc80ef85e6de9ca3727 100644 (file)
@@ -15,7 +15,7 @@ DESCRIPTION
 Examines paths in the working tree that has changes unrecorded
 to the index file, and changes between the index file and the
 current HEAD commit.  The former paths are what you _could_
-commit by running 'git-update-index' before running 'git
+commit by running 'git add' before running 'git
 commit', and the latter paths are what you _would_ commit by
 running 'git commit'.
 
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 b4cbb3830e83cd488936b53687aa6ec92bf4352a..b95f99be6c34ccb7e8583a68d1b1c75a1bf653ca 100644 (file)
@@ -25,15 +25,15 @@ mind.
   an warning if the commit log message given to it does not look
   like a valid UTF-8 string, unless you explicitly say your
   project uses a legacy encoding.  The way to say this is to
-  have core.commitencoding in `.git/config` file, like this:
+  have i18n.commitencoding in `.git/config` file, like this:
 +
 ------------
-[core]
+[i18n]
        commitencoding = ISO-8859-1
 ------------
 +
 Commit objects created with the above setting record the value
-of `core.commitencoding` in its `encoding` header.  This is to
+of `i18n.commitencoding` in its `encoding` header.  This is to
 help other people who look at them later.  Lack of this header
 implies that the commit log message is encoded in UTF-8.
 
@@ -41,15 +41,15 @@ implies that the commit log message is encoded in UTF-8.
   header of a commit object, and tries to re-code the log
   message into UTF-8 unless otherwise specified.  You can
   specify the desired output encoding with
-  `core.logoutputencoding` in `.git/config` file, like this:
+  `i18n.logoutputencoding` in `.git/config` file, like this:
 +
 ------------
-[core]
+[i18n]
        logoutputencoding = ISO-8859-1
 ------------
 +
 If you do not have this configuration variable, the value of
-`core.commitencoding` is used instead.
+`i18n.commitencoding` is used instead.
 
 Note that we deliberately chose not to re-code the commit log
 message when a commit is made to force UTF-8 at the commit
index 8d899927124104d2b472f1ce63f97346a84e2d2c..af8d43bd12624ad8c539ac2dcd0c3c314e0bbff8 100644 (file)
@@ -227,7 +227,7 @@ $ git diff
 @@ -1 +1,2 @@
  hello world!
 +hello world, again
-$ git update-index file.txt
+$ git add file.txt
 $ git diff
 ------------------------------------------------
 
@@ -260,7 +260,7 @@ hello world!
 hello world, again
 ------------------------------------------------
 
-So what our "git update-index" did was store a new blob and then put
+So what our "git add" did was store a new blob and then put
 a reference to it in the index file.  If we modify the file again,
 we'll see that the new modifications are reflected in the "git-diff"
 output:
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 febacd2dc9a91cfd9135a64ee554d14282a105d2..6abde8d7b36865c0c8f43b4489ce0074a27f24c8 100755 (executable)
@@ -6,18 +6,19 @@ DEF_VER=v1.5.0.GIT
 LF='
 '
 
-# First try git-describe, then see if there is a version file
-# (included in release tarballs), then default
-if VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
-   case "$VN" in
-   *$LF*) (exit 1) ;;
-   v[0-9]*) : happy ;;
-   esac
-then
-       VN=$(echo "$VN" | sed -e 's/-/./g');
-elif test -f version
+# First see if there is a version file (included in release tarballs),
+# then try git-describe, then default.
+if test -f version
 then
        VN=$(cat version) || VN="$DEF_VER"
+elif test -d .git &&
+       VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
+       case "$VN" in
+       *$LF*) (exit 1) ;;
+       v[0-9]*) : happy ;;
+       esac
+then
+       VN=$(echo "$VN" | sed -e 's/-/./g');
 else
        VN="$DEF_VER"
 fi
index 40bdcff696f3270ced943945183306fc9899407d..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 \
@@ -939,11 +939,14 @@ check-docs::
                case "$$v" in \
                git-merge-octopus | git-merge-ours | git-merge-recursive | \
                git-merge-resolve | git-merge-stupid | \
+               git-add--interactive | git-fsck-objects | git-init-db | \
+               git-repo-config | \
                git-ssh-pull | git-ssh-push ) continue ;; \
                esac ; \
                test -f "Documentation/$$v.txt" || \
                echo "no doc: $$v"; \
-               grep -q "^gitlink:$$v\[[0-9]\]::" Documentation/git.txt || \
+               sed -e '1,/^__DATA__/d' Documentation/cmd-list.perl | \
+               grep -q "^$$v[  ]" || \
                case "$$v" in \
                git) ;; \
                *) echo "no link: $$v";; \
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 3fefdacd94526b62ac72707d6d80b039f104c06d..abe35387156cf2774c8bc619d74b93c5e83285a8 100644 (file)
@@ -1988,7 +1988,7 @@ static int check_patch(struct patch *patch, struct patch *prev_patch)
                        return error("%s: %s", old_name, strerror(errno));
 
                if (!cached)
-                       st_mode = ntohl(create_ce_mode(st.st_mode));
+                       st_mode = ntohl(ce_mode_from_stat(ce, st.st_mode));
 
                if (patch->is_new < 0)
                        patch->is_new = 0;
index 69fc145a38090488e8da4b60a56154fc999b6fe5..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))
@@ -2200,6 +2203,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
                        if (!strcmp(argv[j], "--"))
                                seen_dashdash = j;
                if (seen_dashdash) {
+                       /* (2) */
                        if (seen_dashdash + 1 != argc - 1)
                                usage(blame_usage);
                        path = add_prefix(prefix, argv[seen_dashdash + 1]);
@@ -2208,6 +2212,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
                }
                else {
                        /* (3) */
+                       if (argc <= i)
+                               usage(blame_usage);
                        path = add_prefix(prefix, argv[i]);
                        if (i + 1 == argc - 1) {
                                final_commit_name = argv[i + 1];
@@ -2348,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, "
index 3ee26059fcf1fb23147fc41971438a823042b9c1..e1199f80ae34a53872ca6a74ae9678053e33db14 100644 (file)
 #include "builtin.h"
 
 static const char diff_files_usage[] =
-"git-diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]"
+"git-diff-files [-q] [-0/-1/2/3 |-c|--cc|-n|--no-index] [<common diff options>] [<path>...]"
 COMMON_DIFF_OPTIONS_HELP;
 
 int cmd_diff_files(int argc, const char **argv, const char *prefix)
 {
        struct rev_info rev;
-       int silent = 0;
+       int nongit = 0;
 
+       prefix = setup_git_directory_gently(&nongit);
        init_revisions(&rev, prefix);
        git_config(git_default_config); /* no "diff" UI options */
        rev.abbrev = 0;
 
        argc = setup_revisions(argc, argv, &rev, NULL);
-       while (1 < argc && argv[1][0] == '-') {
-               if (!strcmp(argv[1], "--base"))
-                       rev.max_count = 1;
-               else if (!strcmp(argv[1], "--ours"))
-                       rev.max_count = 2;
-               else if (!strcmp(argv[1], "--theirs"))
-                       rev.max_count = 3;
-               else if (!strcmp(argv[1], "-q"))
-                       silent = 1;
-               else
-                       usage(diff_files_usage);
-               argv++; argc--;
-       }
        if (!rev.diffopt.output_format)
                rev.diffopt.output_format = DIFF_FORMAT_RAW;
-
-       /*
-        * 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 (rev.pending.nr ||
-           rev.min_age != -1 || rev.max_age != -1)
-               usage(diff_files_usage);
-       if (read_cache() < 0) {
-               perror("read_cache");
-               return -1;
-       }
-       return run_diff_files(&rev, silent);
+       return run_diff_files_cmd(&rev, argc, argv);
 }
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;
-}
index 12d11f0c555d2ba80b2f14d4a43c13733574330e..45faa2067a7f15286216c0323de0bf0ed5ef0f4c 100644 (file)
@@ -25,44 +25,6 @@ struct blobinfo {
 static const char builtin_diff_usage[] =
 "git-diff <options> <rev>{0,2} -- <path>*";
 
-static int builtin_diff_files(struct rev_info *revs,
-                             int argc, const char **argv)
-{
-       int silent = 0;
-       while (1 < argc) {
-               const char *arg = argv[1];
-               if (!strcmp(arg, "--base"))
-                       revs->max_count = 1;
-               else if (!strcmp(arg, "--ours"))
-                       revs->max_count = 2;
-               else if (!strcmp(arg, "--theirs"))
-                       revs->max_count = 3;
-               else if (!strcmp(arg, "-q"))
-                       silent = 1;
-               else
-                       usage(builtin_diff_usage);
-               argv++; argc--;
-       }
-       /*
-        * Make sure there are NO revision (i.e. pending object) parameter,
-        * specified rev.max_count is reasonable (0 <= n <= 3), and
-        * there is no other revision filtering parameter.
-        */
-       if (revs->pending.nr ||
-           revs->min_age != -1 ||
-           revs->max_age != -1 ||
-           3 < revs->max_count)
-               usage(builtin_diff_usage);
-       if (revs->max_count < 0 &&
-           (revs->diffopt.output_format & DIFF_FORMAT_PATCH))
-               revs->combine_merges = revs->dense_combined_merges = 1;
-       if (read_cache() < 0) {
-               perror("read_cache");
-               return -1;
-       }
-       return run_diff_files(revs, silent);
-}
-
 static void stuff_change(struct diff_options *opt,
                         unsigned old_mode, unsigned new_mode,
                         const unsigned char *old_sha1,
@@ -226,6 +188,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
        int ents = 0, blobs = 0, paths = 0;
        const char *path = NULL;
        struct blobinfo blob[2];
+       int nongit = 0;
 
        /*
         * We could get N tree-ish in the rev.pending_objects list.
@@ -247,6 +210,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
         * Other cases are errors.
         */
 
+       prefix = setup_git_directory_gently(&nongit);
        git_config(git_diff_ui_config);
        init_revisions(&rev, prefix);
 
@@ -322,7 +286,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
        if (!ents) {
                switch (blobs) {
                case 0:
-                       return builtin_diff_files(&rev, argc, argv);
+                       return run_diff_files_cmd(&rev, argc, argv);
                        break;
                case 1:
                        if (paths != 1)
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 1bb3a06680194ce5855185ad1a1c7e39eeebba94..c2db5a5b037babf9020353d9b11dc348915b6c1b 100644 (file)
@@ -226,6 +226,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
        int i;
        int read_from_stdin = 0;
 
+       git_config(git_default_config);
        init_revisions(&revs, prefix);
        revs.abbrev = 0;
        revs.commit_format = CMIT_FMT_UNSPECIFIED;
index 3fbdc67b8880a7d1b46e39d1b7d03c00d65b1408..65246dad8d075de3f77454494c419000288c9ed2 100644 (file)
@@ -109,16 +109,17 @@ static int add_file_to_cache(const char *path)
        ce->ce_flags = htons(namelen);
        fill_stat_cache_info(ce, &st);
 
-       ce->ce_mode = create_ce_mode(st.st_mode);
-       if (!trust_executable_bit) {
+       if (trust_executable_bit)
+               ce->ce_mode = create_ce_mode(st.st_mode);
+       else {
                /* If there is an existing entry, pick the mode bits
                 * from it, otherwise assume unexecutable.
                 */
+               struct cache_entry *ent;
                int pos = cache_name_pos(path, namelen);
-               if (0 <= pos)
-                       ce->ce_mode = active_cache[pos]->ce_mode;
-               else if (S_ISREG(st.st_mode))
-                       ce->ce_mode = create_ce_mode(S_IFREG | 0666);
+
+               ent = (0 <= pos) ? active_cache[pos] : NULL;
+               ce->ce_mode = ce_mode_from_stat(ent, st.st_mode);
        }
 
        if (index_path(ce->sha1, path, &st, !info_only))
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);
diff --git a/cache.h b/cache.h
index c62b0b090d2b3e628764557127f1629d26459fbf..04f8e63baf6c23d9a27618b642b98506c9db688a 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -106,6 +106,16 @@ static inline unsigned int create_ce_mode(unsigned int mode)
                return htonl(S_IFLNK);
        return htonl(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;
+       if (!trust_executable_bit && S_ISREG(mode)) {
+               if (ce && S_ISREG(ntohl(ce->ce_mode)))
+                       return ce->ce_mode;
+               return create_ce_mode(0666);
+       }
+       return create_ce_mode(mode);
+}
 #define canon_mode(mode) \
        (S_ISREG(mode) ? (S_IFREG | ce_permissions(mode)) : \
        S_ISLNK(mode) ? S_IFLNK : S_IFDIR)
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 d82107124a53bca99ee65ea31dceb3871bf6796f..c938aa0b15513265866b88dbb9b8217958cac376 100644 (file)
--- a/config.c
+++ b/config.c
@@ -310,12 +310,14 @@ int git_default_config(const char *var, const char *value)
        }
 
        if (!strcmp(var, "core.packedgitwindowsize")) {
-               int pgsz = getpagesize();
+               int pgsz_x2 = getpagesize() * 2;
                packed_git_window_size = git_config_int(var, value);
-               packed_git_window_size /= pgsz;
-               if (packed_git_window_size < 2)
-                       packed_git_window_size = 2;
-               packed_git_window_size *= pgsz;
+
+               /* This value must be multiple of (pagesize * 2) */
+               packed_git_window_size /= pgsz_x2;
+               if (packed_git_window_size < 1)
+                       packed_git_window_size = 1;
+               packed_git_window_size *= pgsz_x2;
                return 0;
        }
 
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
index 2a20ca55cbe912a8ddd4bea8b2476ae30215903a..66f8d6f03d91d7dfa4a164137ee0310ca26dc1aa 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -773,6 +773,7 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
        char pbuf[NI_MAXSERV];
        struct addrinfo hints, *ai0, *ai;
        int gai;
+       long flags;
 
        sprintf(pbuf, "%d", listen_port);
        memset(&hints, 0, sizeof(hints));
@@ -820,6 +821,10 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
                        continue;       /* not fatal */
                }
 
+               flags = fcntl(sockfd, F_GETFD, 0);
+               if (flags >= 0)
+                       fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);
+
                socklist = xrealloc(socklist, sizeof(int) * (socknum + 1));
                socklist[socknum++] = sockfd;
 
@@ -839,6 +844,7 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
 {
        struct sockaddr_in sin;
        int sockfd;
+       long flags;
 
        memset(&sin, 0, sizeof sin);
        sin.sin_family = AF_INET;
@@ -871,6 +877,10 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
                return 0;
        }
 
+       flags = fcntl(sockfd, F_GETFD, 0);
+       if (flags >= 0)
+               fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);
+
        *socklist_p = xmalloc(sizeof(int));
        **socklist_p = sockfd;
        return 1;
index 278ba79ee633b8109be2083597d43286c0ae08d8..1d184422a5e8645684702e239051948ca386d318 100644 (file)
 #include "diffcore.h"
 #include "revision.h"
 #include "cache-tree.h"
+#include "path-list.h"
 
 /*
  * 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(xstrdup(e->d_name), list);
+
+       closedir(dir);
+       return 0;
+}
+
+static int queue_diff(struct diff_options *o,
+               const char *name1, const char *name2)
+{
+       struct stat st;
+       int mode1 = 0, mode2 = 0;
+
+       if (name1) {
+               if (stat(name1, &st))
+                       return error("Could not access '%s'", name1);
+               mode1 = st.st_mode;
+       }
+       if (name2) {
+               if (stat(name2, &st))
+                       return error("Could not access '%s'", name1);
+               mode2 = st.st_mode;
+       }
+
+       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 (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;
+       }
+}
+
+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 == '/';
+}
+
+static int handle_diff_files_args(struct rev_info *revs,
+               int argc, const char **argv, int *silent)
+{
+       *silent = 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;
+               else if (!strcmp(argv[1], "-q"))
+                       *silent = 1;
+               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;
+       }
+
+       /*
+        * 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;
+}
+
+int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv)
+{
+       int silent_on_removed;
+
+       if (handle_diff_files_args(revs, argc, argv, &silent_on_removed))
+               return -1;
+
+       if (revs->max_count == -2) {
+               if (revs->diffopt.nr_paths != 2)
+                       return error("need two files/directories with --no-index");
+               queue_diff(&revs->diffopt, revs->diffopt.paths[0],
+                               revs->diffopt.paths[1]);
+               diffcore_std(&revs->diffopt);
+               diff_flush(&revs->diffopt);
+               return 0;
+       }
+
+       if (read_cache() < 0) {
+               perror("read_cache");
+               return -1;
+       }
+       return run_diff_files(revs, silent_on_removed);
+}
+
 int run_diff_files(struct rev_info *revs, int silent_on_removed)
 {
        int entries, i;
@@ -166,9 +377,7 @@ static int get_stat_data(struct cache_entry *ce,
                }
                changed = ce_match_stat(ce, &st, 0);
                if (changed) {
-                       mode = create_ce_mode(st.st_mode);
-                       if (!trust_executable_bit && S_ISREG(st.st_mode))
-                               mode = ce->ce_mode;
+                       mode = ce_mode_from_stat(ce, st.st_mode);
                        sha1 = no_sha1;
                }
        }
diff --git a/diff.c b/diff.c
index 13b9b6c5602cc1aca4a95ed4d292756d3380c543..701880abadd4bd93b492d2cd73e164d8a95c20ac 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"))
@@ -2390,7 +2406,8 @@ static void diff_resolve_rename_copy(void)
                                p->status = DIFF_STATUS_RENAMED;
                }
                else if (hashcmp(p->one->sha1, p->two->sha1) ||
-                        p->one->mode != p->two->mode)
+                        p->one->mode != p->two->mode ||
+                        is_null_sha1(p->one->sha1))
                        p->status = DIFF_STATUS_MODIFIED;
                else {
                        /* This is a "no-change" entry and should not
diff --git a/diff.h b/diff.h
index eece65ddccdb7bd8bf51af80af92e29b4eb76f37..b608828261c9a7bb4b60c030109d078841acb114 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -219,6 +219,7 @@ 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);
+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);
 
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)",
index c1bcb001a51324ebcb66bfb0a695e20ff366df02..105ac28f9766cb8800fcf6071fd94ed0e3cdf90a 100644 (file)
@@ -96,11 +96,14 @@ extern void set_warn_routine(void (*routine)(const char *warn, va_list params));
 extern void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
 extern int git_munmap(void *start, size_t length);
 
+/* This value must be multiple of (pagesize * 2) */
 #define DEFAULT_PACKED_GIT_WINDOW_SIZE (1 * 1024 * 1024)
 
 #else /* NO_MMAP */
 
 #include <sys/mman.h>
+
+/* This value must be multiple of (pagesize * 2) */
 #define DEFAULT_PACKED_GIT_WINDOW_SIZE \
        (sizeof(void*) >= 8 \
                ?  1 * 1024 * 1024 * 1024 \
index 04a5eb0f297a691fa0520d1729ea20bd66a53bd9..498c938c4507ccdc27f5a9e30e85f013a067c876 100755 (executable)
@@ -254,12 +254,15 @@ esac
 
 for s in $use_strategies
 do
-       case " $s " in
-       *" $no_trivial_merge_strategies "*)
-               index_merge=f
-               break
-               ;;
-       esac
+       for nt in $no_trivial_merge_strategies
+       do
+               case " $s " in
+               *" $nt "*)
+                       index_merge=f
+                       break
+                       ;;
+               esac
+       done
 done
 
 case "$#" in
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..79fc73ca46b298533e2ebf8b7314ab33cf3b3cbf 100644 (file)
--- a/git.c
+++ b/git.c
@@ -237,10 +237,9 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
                { "config", cmd_config },
                { "count-objects", cmd_count_objects, RUN_SETUP },
                { "describe", cmd_describe, RUN_SETUP },
-               { "diff", cmd_diff, RUN_SETUP | USE_PAGER },
-               { "diff-files", cmd_diff_files, RUN_SETUP },
+               { "diff", cmd_diff, USE_PAGER },
+               { "diff-files", cmd_diff_files },
                { "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 c54a61187711087b98138b9598db6353457e4df3..605b35239674c72a272e1c0fc1fb886c4b75be46 100644 (file)
@@ -344,16 +344,17 @@ int add_file_to_index(const char *path, int verbose)
        ce->ce_flags = htons(namelen);
        fill_stat_cache_info(ce, &st);
 
-       ce->ce_mode = create_ce_mode(st.st_mode);
-       if (!trust_executable_bit) {
+       if (trust_executable_bit)
+               ce->ce_mode = create_ce_mode(st.st_mode);
+       else {
                /* If there is an existing entry, pick the mode bits
                 * from it, otherwise assume unexecutable.
                 */
+               struct cache_entry *ent;
                int pos = cache_name_pos(path, namelen);
-               if (pos >= 0)
-                       ce->ce_mode = active_cache[pos]->ce_mode;
-               else if (S_ISREG(st.st_mode))
-                       ce->ce_mode = create_ce_mode(S_IFREG | 0666);
+
+               ent = (0 <= pos) ? active_cache[pos] : NULL;
+               ce->ce_mode = ce_mode_from_stat(ent, st.st_mode);
        }
 
        if (index_path(ce->sha1, path, &st, 1))
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 8ad7fad825708b5a56a3bfd4b8b98708de0bb2dc..2c870314d525ba0666470d53cf7901a2bac9e3c0 100644 (file)
@@ -407,7 +407,6 @@ static unsigned int peak_pack_open_windows;
 static unsigned int pack_open_windows;
 static size_t peak_pack_mapped;
 static size_t pack_mapped;
-static size_t page_size;
 struct packed_git *packed_git;
 
 void pack_report()
@@ -416,7 +415,7 @@ void pack_report()
                "pack_report: getpagesize()            = %10" SZ_FMT "\n"
                "pack_report: core.packedGitWindowSize = %10" SZ_FMT "\n"
                "pack_report: core.packedGitLimit      = %10" SZ_FMT "\n",
-               page_size,
+               (size_t) getpagesize(),
                packed_git_window_size,
                packed_git_limit);
        fprintf(stderr,
@@ -662,10 +661,9 @@ unsigned char* use_pack(struct packed_git *p,
                                break;
                }
                if (!win) {
-                       if (!page_size)
-                               page_size = getpagesize();
+                       size_t window_align = packed_git_window_size / 2;
                        win = xcalloc(1, sizeof(*win));
-                       win->offset = (offset / page_size) * page_size;
+                       win->offset = (offset / window_align) * window_align;
                        win->len = p->pack_size - win->offset;
                        if (win->len > packed_git_window_size)
                                win->len = packed_git_window_size;
@@ -1547,11 +1545,13 @@ int pretend_sha1_file(void *buf, unsigned long len, const char *type, unsigned c
        co = &cached_objects[cached_object_nr++];
        co->size = len;
        co->type = strdup(type);
+       co->buf = xmalloc(len);
+       memcpy(co->buf, buf, len);
        hashcpy(co->sha1, sha1);
        return 0;
 }
 
-void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)
+void *read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size)
 {
        unsigned long mapsize;
        void *map, *buf;
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 caaab26c2f3f2d04581a6c6918ab36f97a51f975..08e035220cfd5c2da0798eba84c779981f185b4a 100755 (executable)
@@ -30,6 +30,16 @@ test_expect_success \
         *) echo fail; git-ls-files --stage xfoo1; (exit 1);;
         esac'
 
+test_expect_success 'git-add: filemode=0 should not get confused by symlink' '
+       rm -f xfoo1 &&
+       ln -s foo xfoo1 &&
+       git-add xfoo1 &&
+       case "`git-ls-files --stage xfoo1`" in
+       120000" "*xfoo1) echo ok;;
+       *) echo fail; git-ls-files --stage xfoo1; (exit 1);;
+       esac
+'
+
 test_expect_success \
        'git-update-index --add: Test that executable bit is not used...' \
        'git config core.filemode 0 &&
@@ -41,6 +51,16 @@ test_expect_success \
         *) echo fail; git-ls-files --stage xfoo2; (exit 1);;
         esac'
 
+test_expect_success 'git-add: filemode=0 should not get confused by symlink' '
+       rm -f xfoo2 &&
+       ln -s foo xfoo2 &&
+       git update-index --add xfoo2 &&
+       case "`git-ls-files --stage xfoo2`" in
+       120000" "*xfoo2) echo ok;;
+       *) echo fail; git-ls-files --stage xfoo2; (exit 1);;
+       esac
+'
+
 test_expect_success \
        'git-update-index --add: Test that executable bit is not used...' \
        'git config core.filemode 0 &&
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);