summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/RelNotes-1.5.0.1.txt42
-rw-r--r--Documentation/RelNotes-1.5.0.2.txt59
-rw-r--r--Documentation/RelNotes-1.5.0.txt43
-rwxr-xr-xDocumentation/cmd-list.perl1
-rw-r--r--Documentation/config.txt27
-rw-r--r--Documentation/core-intro.txt3
-rw-r--r--Documentation/git-checkout.txt7
-rw-r--r--Documentation/git-clone.txt4
-rw-r--r--Documentation/git-fast-import.txt2
-rw-r--r--Documentation/git-merge.txt2
-rw-r--r--Documentation/git-rebase.txt24
-rw-r--r--Documentation/git-rerere.txt3
-rw-r--r--Documentation/git-reset.txt4
-rw-r--r--Documentation/git-runstatus.txt2
-rw-r--r--Documentation/git-status.txt2
-rw-r--r--Documentation/i18n.txt12
-rw-r--r--Documentation/tutorial-2.txt4
-rwxr-xr-xGIT-VERSION-GEN23
-rw-r--r--Makefile21
l---------RelNotes2
-rw-r--r--builtin-apply.c2
-rw-r--r--builtin-blame.c3
-rw-r--r--builtin-diff.c3
-rw-r--r--builtin-log.c28
-rw-r--r--builtin-pack-objects.c12
-rw-r--r--builtin-rerere.c16
-rw-r--r--builtin-rev-list.c1
-rw-r--r--builtin-show-ref.c6
-rw-r--r--builtin-update-index.c13
-rw-r--r--cache.h10
-rw-r--r--compat/strtoumax.c10
-rw-r--r--config.c12
-rwxr-xr-xcontrib/fast-import/import-tars.perl9
-rw-r--r--daemon.c10
-rw-r--r--diff-lib.c4
-rw-r--r--diff.c6
-rw-r--r--fast-import.c32
-rwxr-xr-xgit-am.sh2
-rwxr-xr-xgit-commit.sh4
-rw-r--r--git-compat-util.h8
-rw-r--r--git-gui/.gitignore1
-rwxr-xr-xgit-gui/CREDITS-GEN71
-rwxr-xr-xgit-gui/GIT-VERSION-GEN17
-rw-r--r--git-gui/Makefile23
-rw-r--r--git-gui/TODO44
-rwxr-xr-xgit-gui/git-gui.sh285
-rwxr-xr-xgit-merge.sh15
-rw-r--r--read-cache.c13
-rw-r--r--sha1_file.c12
-rwxr-xr-xt/t3700-add.sh20
50 files changed, 717 insertions, 262 deletions
diff --git a/Documentation/RelNotes-1.5.0.1.txt b/Documentation/RelNotes-1.5.0.1.txt
new file mode 100644
index 0000000000..fea3f9935b
--- /dev/null
+++ b/Documentation/RelNotes-1.5.0.1.txt
@@ -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.
diff --git a/Documentation/RelNotes-1.5.0.2.txt b/Documentation/RelNotes-1.5.0.2.txt
new file mode 100644
index 0000000000..4dc1344859
--- /dev/null
+++ b/Documentation/RelNotes-1.5.0.2.txt
@@ -0,0 +1,59 @@
+GIT v1.5.0.2 Release Notes
+==========================
+
+Fixes since v1.5.0.1
+--------------------
+
+* Bugfixes
+
+ - 'git diff maint master next' did not correctly give combined
+ diff across three trees.
+
+ - 'git fast-import' portability fix for Solaris.
+
+ - 'git show-ref --verify' without arguments did not error out
+ but segfaulted.
+
+ - 'git diff :tracked-file `pwd`/an-untracked-file' gave an extra
+ slashes after a/ and b/.
+
+ - 'git format-patch' produced too long filenames if the commit
+ message had too long line at the beginning.
+
+ - Running 'make all' and then without changing anything
+ running 'make install' still rebuilt some files. This
+ was inconvenient when building as yourself and then
+ installing as root (especially problematic when the source
+ directory is on NFS and root is mapped to nobody).
+
+ - 'git-rerere' failed to deal with two unconflicted paths that
+ sorted next to each other.
+
+ - 'git-rerere' attempted to open(2) a symlink and failed if
+ there was a conflict. Since a conflicting change to a
+ symlink would not benefit from rerere anyway, the command
+ now ignores conflicting changes to symlinks.
+
+ - 'git-repack' did not like to pass more than 64 arguments
+ internally to underlying 'rev-list' logic, which made it
+ impossible to repack after accumulating many (small) packs
+ in the repository.
+
+* Documentation updates
+
+ - added and clarified core.bare, core.legacyheaders configurations.
+
+ - updated "git-clone --depth" documentation.
+
+* Assorted git-gui fixes.
+
+
+--
+exec >/var/tmp/1
+O=v1.5.0.1-35-gffa84ff
+echo O=`git describe maint`
+git shortlog --no-merges $O..maint
+
+#Local Variables:
+#mode: text
+#End:
diff --git a/Documentation/RelNotes-1.5.0.txt b/Documentation/RelNotes-1.5.0.txt
index 84e7eaf3c8..daf4bdb0d7 100644
--- a/Documentation/RelNotes-1.5.0.txt
+++ b/Documentation/RelNotes-1.5.0.txt
@@ -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
@@ -447,7 +448,7 @@ Updates in v1.5.0 since v1.4.4 series
- There is a partial support for 'shallow' repositories that
keeps only recent history. A 'shallow clone' is created by
specifying how deep that truncated history should be
- (e.g. "git clone --depth=5 git://some.where/repo.git").
+ (e.g. "git clone --depth 5 git://some.where/repo.git").
Currently a shallow repository has number of limitations:
diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl
index 69003e90af..75f4791055 100755
--- a/Documentation/cmd-list.perl
+++ b/Documentation/cmd-list.perl
@@ -146,6 +146,7 @@ git-reflog ancillarymanipulators
git-relink ancillarymanipulators
git-repack ancillarymanipulators
git-config ancillarymanipulators
+git-remote ancillarymanipulators
git-request-pull foreignscminterface
git-rerere ancillaryinterrogators
git-reset mainporcelain
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 38655350f2..9fec76935e 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -142,6 +142,18 @@ core.preferSymlinkRefs::
This is sometimes needed to work with old scripts that
expect HEAD to be a symbolic link.
+core.bare::
+ If true this repository is assumed to be 'bare' and has no
+ working directory associated with it. If this is the case a
+ number of commands that require a working directory will be
+ disabled, such as gitlink:git-add[1] or gitlink:git-merge[1].
++
+This setting is automatically guessed by gitlink:git-clone[1] or
+gitlink:git-init[1] when the repository was created. By default a
+repository that ends in "/.git" is assumed to be not bare (bare =
+false), while all other repositories are assumed to be bare (bare
+= true).
+
core.logAllRefUpdates::
Updates to a ref <ref> is logged to the file
"$GIT_DIR/logs/<ref>", by appending the new and old
@@ -180,10 +192,17 @@ core.compression::
slowest.
core.legacyheaders::
- A boolean which enables the legacy object header format in case
- you want to interoperate with old clients accessing the object
- database directly (where the "http://" and "rsync://" protocols
- count as direct access).
+ A boolean which
+ changes the format of loose objects so that they are more
+ efficient to pack and to send out of the repository over git
+ native protocol, since v1.4.2. However, loose objects
+ written in the new format cannot be read by git older than
+ that version; people fetching from your repository using
+ older versions of git over dumb transports (e.g. http)
+ will also be affected.
++
+To let git use the new loose object format, you have to
+set core.legacyheaders to false.
core.packedGitWindowSize::
Number of bytes of a pack file to map into memory in a
diff --git a/Documentation/core-intro.txt b/Documentation/core-intro.txt
index abafefc71c..6bee448e7d 100644
--- a/Documentation/core-intro.txt
+++ b/Documentation/core-intro.txt
@@ -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
~~~~~~~~~~~
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index e4ffde4fdd..1ae77be450 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -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
------------
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 707376f22c..6d32c491a5 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -11,7 +11,7 @@ SYNOPSIS
[verse]
'git-clone' [--template=<template_directory>] [-l [-s]] [-q] [-n] [--bare]
[-o <name>] [-u <upload-pack>] [--reference <repository>]
- [--depth=<depth>] <repository> [<directory>]
+ [--depth <depth>] <repository> [<directory>]
DESCRIPTION
-----------
@@ -96,7 +96,7 @@ OPTIONS
if unset the templates are taken from the installation
defined default, typically `/usr/share/git-core/templates`.
---depth=<depth>::
+--depth <depth>::
Create a 'shallow' clone with a history truncated to the
specified number of revs. A shallow repository has
number of limitations (you cannot clone or fetch from
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index 445f6b8544..77a14bb076 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -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
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index e53ff4b4e7..9c08efa53a 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -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.
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index f2ef1f7dc0..2f417a8f85 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -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
diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt
index 139b6eb773..7ff9b05e68 100644
--- a/Documentation/git-rerere.txt
+++ b/Documentation/git-rerere.txt
@@ -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
diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt
index 04475a9216..5b55cda512 100644
--- a/Documentation/git-reset.txt
+++ b/Documentation/git-reset.txt
@@ -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-runstatus.txt b/Documentation/git-runstatus.txt
index 89d7b92731..8bb52f4687 100644
--- a/Documentation/git-runstatus.txt
+++ b/Documentation/git-runstatus.txt
@@ -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'.
diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt
index 03871e5d73..e9e193f008 100644
--- a/Documentation/git-status.txt
+++ b/Documentation/git-status.txt
@@ -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'.
diff --git a/Documentation/i18n.txt b/Documentation/i18n.txt
index b4cbb3830e..b95f99be6c 100644
--- a/Documentation/i18n.txt
+++ b/Documentation/i18n.txt
@@ -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
diff --git a/Documentation/tutorial-2.txt b/Documentation/tutorial-2.txt
index 8d89992712..af8d43bd12 100644
--- a/Documentation/tutorial-2.txt
+++ b/Documentation/tutorial-2.txt
@@ -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:
diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index febacd2dc9..9133a00b23 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,23 +1,24 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.5.0.GIT
+DEF_VER=v1.5.0.1.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
diff --git a/Makefile b/Makefile
index 40bdcff696..64d29f7c18 100644
--- a/Makefile
+++ b/Makefile
@@ -28,6 +28,10 @@ all::
#
# Define NO_STRLCPY if you don't have strlcpy.
#
+# Define NO_STRTOUMAX if you don't have strtoumax in the C library.
+# If your compiler also does not support long long or does not have
+# strtoull, define NO_STRTOULL.
+#
# Define NO_SETENV if you don't have setenv in the C library.
#
# Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
@@ -353,11 +357,13 @@ ifeq ($(uname_S),SunOS)
NO_UNSETENV = YesPlease
NO_SETENV = YesPlease
NO_C99_FORMAT = YesPlease
+ NO_STRTOUMAX = YesPlease
endif
ifeq ($(uname_R),5.9)
NO_UNSETENV = YesPlease
NO_SETENV = YesPlease
NO_C99_FORMAT = YesPlease
+ NO_STRTOUMAX = YesPlease
endif
INSTALL = ginstall
TAR = gtar
@@ -517,6 +523,13 @@ ifdef NO_STRLCPY
COMPAT_CFLAGS += -DNO_STRLCPY
COMPAT_OBJS += compat/strlcpy.o
endif
+ifdef NO_STRTOUMAX
+ COMPAT_CFLAGS += -DNO_STRTOUMAX
+ COMPAT_OBJS += compat/strtoumax.o
+endif
+ifdef NO_STRTOULL
+ COMPAT_CFLAGS += -DNO_STRTOULL
+endif
ifdef NO_SETENV
COMPAT_CFLAGS += -DNO_SETENV
COMPAT_OBJS += compat/setenv.o
@@ -882,7 +895,8 @@ dist: git.spec git-archive
$(TAR) rf $(GIT_TARNAME).tar \
$(GIT_TARNAME)/git.spec \
$(GIT_TARNAME)/version \
- $(GIT_TARNAME)/git-gui/version
+ $(GIT_TARNAME)/git-gui/version \
+ $(GIT_TARNAME)/git-gui/credits
@rm -rf $(GIT_TARNAME)
gzip -f -9 $(GIT_TARNAME).tar
@@ -939,11 +953,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";; \
diff --git a/RelNotes b/RelNotes
index 4571d0d1cf..5308f6b956 120000
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes-1.5.0.txt \ No newline at end of file
+Documentation/RelNotes-1.5.0.2.txt \ No newline at end of file
diff --git a/builtin-apply.c b/builtin-apply.c
index 3fefdacd94..abe3538715 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -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;
diff --git a/builtin-blame.c b/builtin-blame.c
index 69fc145a38..1a752b95bb 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -2200,6 +2200,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 +2209,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];
diff --git a/builtin-diff.c b/builtin-diff.c
index a6590205e8..c387ebb16c 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -192,7 +192,8 @@ static int builtin_diff_combined(struct rev_info *revs,
parent = xmalloc(ents * sizeof(*parent));
/* Again, the revs are all reverse */
for (i = 0; i < ents; i++)
- hashcpy((unsigned char*)parent + i, ent[ents - 1 - i].item->sha1);
+ hashcpy((unsigned char *)(parent + i),
+ ent[ents - 1 - i].item->sha1);
diff_tree_combined(parent[0], parent + 1, ents - 1,
revs->dense_combined_merges, revs);
return 0;
diff --git a/builtin-log.c b/builtin-log.c
index af2de54371..a5e4b625f8 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -224,6 +224,9 @@ int cmd_log(int argc, const char **argv, const char *prefix)
return cmd_log_walk(&rev);
}
+/* format-patch */
+#define FORMAT_PATCH_NAME_MAX 64
+
static int istitlechar(char c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
@@ -264,15 +267,18 @@ static int git_format_config(const char *var, const char *value)
static FILE *realstdout = NULL;
static const char *output_directory = NULL;
-static void reopen_stdout(struct commit *commit, int nr, int keep_subject)
+static int reopen_stdout(struct commit *commit, int nr, int keep_subject)
{
- char filename[1024];
+ char filename[PATH_MAX];
char *sol;
int len = 0;
- int suffix_len = strlen(fmt_patch_suffix) + 10; /* ., NUL and slop */
+ int suffix_len = strlen(fmt_patch_suffix) + 1;
if (output_directory) {
- strlcpy(filename, output_directory, 1000);
+ if (strlen(output_directory) >=
+ sizeof(filename) - FORMAT_PATCH_NAME_MAX - suffix_len)
+ return error("name of output directory is too long");
+ strlcpy(filename, output_directory, sizeof(filename) - suffix_len);
len = strlen(filename);
if (filename[len - 1] != '/')
filename[len++] = '/';
@@ -297,7 +303,8 @@ static void reopen_stdout(struct commit *commit, int nr, int keep_subject)
}
for (j = 0;
- len < sizeof(filename) - suffix_len &&
+ j < FORMAT_PATCH_NAME_MAX - suffix_len - 5 &&
+ len < sizeof(filename) - suffix_len &&
sol[j] && sol[j] != '\n';
j++) {
if (istitlechar(sol[j])) {
@@ -314,10 +321,16 @@ static void reopen_stdout(struct commit *commit, int nr, int keep_subject)
}
while (filename[len - 1] == '.' || filename[len - 1] == '-')
len--;
+ filename[len] = 0;
}
+ if (len + suffix_len >= sizeof(filename))
+ return error("Patch pathname too long");
strcpy(filename + len, fmt_patch_suffix);
fprintf(realstdout, "%s\n", filename);
- freopen(filename, "w", stdout);
+ if (freopen(filename, "w", stdout) == NULL)
+ return error("Cannot open patch file %s",filename);
+ return 0;
+
}
static int get_patch_id(struct commit *commit, struct diff_options *options,
@@ -573,7 +586,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
rev.message_id = message_id;
}
if (!use_stdout)
- reopen_stdout(commit, rev.nr, keep_subject);
+ if (reopen_stdout(commit, rev.nr, keep_subject))
+ die("Failed to create output files");
shown = log_tree_commit(&rev, commit);
free(commit->buffer);
commit->buffer = NULL;
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 3824ee33ac..971388276a 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -1551,9 +1551,12 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
int use_internal_rev_list = 0;
int thin = 0;
int i;
- const char *rp_av[64];
+ const char **rp_av;
+ int rp_ac_alloc = 64;
int rp_ac;
+ rp_av = xcalloc(rp_ac_alloc, sizeof(*rp_av));
+
rp_av[0] = "pack-objects";
rp_av[1] = "--objects"; /* --thin will make it --objects-edge */
rp_ac = 2;
@@ -1626,8 +1629,11 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
!strcmp("--reflog", arg) ||
!strcmp("--all", arg)) {
use_internal_rev_list = 1;
- if (ARRAY_SIZE(rp_av) - 1 <= rp_ac)
- die("too many internal rev-list options");
+ if (rp_ac >= rp_ac_alloc - 1) {
+ rp_ac_alloc = alloc_nr(rp_ac_alloc);
+ rp_av = xrealloc(rp_av,
+ rp_ac_alloc * sizeof(*rp_av));
+ }
rp_av[rp_ac++] = arg;
continue;
}
diff --git a/builtin-rerere.c b/builtin-rerere.c
index 318d959d89..58c5fed91d 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -154,13 +154,17 @@ static int find_conflict(struct path_list *conflict)
return error("Could not read index");
for (i = 0; i + 2 < active_nr; i++) {
struct cache_entry *e1 = active_cache[i];
- struct cache_entry *e2 = active_cache[i + 1];
- struct cache_entry *e3 = active_cache[i + 2];
- if (ce_stage(e1) == 1 && ce_stage(e2) == 2 &&
- ce_stage(e3) == 3 && ce_same_name(e1, e2) &&
- ce_same_name(e1, e3)) {
+ struct cache_entry *e2 = active_cache[i+1];
+ struct cache_entry *e3 = active_cache[i+2];
+ if (ce_stage(e1) == 1 &&
+ ce_stage(e2) == 2 &&
+ ce_stage(e3) == 3 &&
+ ce_same_name(e1, e2) && ce_same_name(e1, e3) &&
+ S_ISREG(ntohl(e1->ce_mode)) &&
+ S_ISREG(ntohl(e2->ce_mode)) &&
+ S_ISREG(ntohl(e3->ce_mode))) {
path_list_insert((const char *)e1->name, conflict);
- i += 3;
+ i += 2;
}
}
return 0;
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 1bb3a06680..c2db5a5b03 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -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;
diff --git a/builtin-show-ref.c b/builtin-show-ref.c
index 853f13f6ae..75211e64f9 100644
--- a/builtin-show-ref.c
+++ b/builtin-show-ref.c
@@ -221,9 +221,11 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix)
}
if (verify) {
- unsigned char sha1[20];
-
+ if (!pattern)
+ die("--verify requires a reference");
while (*pattern) {
+ unsigned char sha1[20];
+
if (!strncmp(*pattern, "refs/", 5) &&
resolve_ref(*pattern, sha1, 1, NULL)) {
if (!quiet)
diff --git a/builtin-update-index.c b/builtin-update-index.c
index 1ac613a788..772aaba7bb 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -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))
diff --git a/cache.h b/cache.h
index c62b0b090d..04f8e63baf 100644
--- 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)
diff --git a/compat/strtoumax.c b/compat/strtoumax.c
new file mode 100644
index 0000000000..5541353a77
--- /dev/null
+++ b/compat/strtoumax.c
@@ -0,0 +1,10 @@
+#include "../git-compat-util.h"
+
+uintmax_t gitstrtoumax (const char *nptr, char **endptr, int base)
+{
+#if defined(NO_STRTOULL)
+ return strtoul(nptr, endptr, base);
+#else
+ return strtoull(nptr, endptr, base);
+#endif
+}
diff --git a/config.c b/config.c
index d82107124a..c938aa0b15 100644
--- 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;
}
diff --git a/contrib/fast-import/import-tars.perl b/contrib/fast-import/import-tars.perl
index 990c9e70b2..5585a8b2c5 100755
--- a/contrib/fast-import/import-tars.perl
+++ b/contrib/fast-import/import-tars.perl
@@ -25,11 +25,14 @@ foreach my $tar_file (@ARGV)
my $tar_name = $1;
if ($tar_name =~ s/\.(tar\.gz|tgz)$//) {
- open(I, '-|', 'gzcat', $tar_file) or die "Unable to gzcat $tar_file: $!\n";
+ open(I, '-|', 'gunzip', '-c', $tar_file)
+ or die "Unable to gunzip -c $tar_file: $!\n";
} elsif ($tar_name =~ s/\.(tar\.bz2|tbz2)$//) {
- open(I, '-|', 'bzcat', $tar_file) or die "Unable to bzcat $tar_file: $!\n";
+ open(I, '-|', 'bunzip2', '-c', $tar_file)
+ or die "Unable to bunzip2 -c $tar_file: $!\n";
} elsif ($tar_name =~ s/\.tar\.Z$//) {
- open(I, '-|', 'zcat', $tar_file) or die "Unable to zcat $tar_file: $!\n";
+ open(I, '-|', 'uncompress', '-c', $tar_file)
+ or die "Unable to uncompress -c $tar_file: $!\n";
} elsif ($tar_name =~ s/\.tar$//) {
open(I, $tar_file) or die "Unable to open $tar_file: $!\n";
} else {
diff --git a/daemon.c b/daemon.c
index 2a20ca55cb..66f8d6f03d 100644
--- 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;
diff --git a/diff-lib.c b/diff-lib.c
index 91cd87742f..556d5345bf 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -170,9 +170,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 13b9b6c560..b8a90e91a9 100644
--- a/diff.c
+++ b/diff.c
@@ -211,6 +211,8 @@ static void emit_rewrite_diff(const char *name_a,
diff_populate_filespec(two, 0);
lc_a = count_lines(one->data, one->size);
lc_b = count_lines(two->data, two->size);
+ name_a += (*name_a == '/');
+ name_b += (*name_b == '/');
printf("--- a/%s\n+++ b/%s\n@@ -", name_a, name_b);
print_line_count(lc_a);
printf(" +");
@@ -1020,8 +1022,8 @@ static void builtin_diff(const char *name_a,
const char *set = diff_get_color(o->color_diff, DIFF_METAINFO);
const char *reset = diff_get_color(o->color_diff, DIFF_RESET);
- a_one = quote_two("a/", name_a);
- b_two = quote_two("b/", name_b);
+ a_one = quote_two("a/", name_a + (*name_a == '/'));
+ b_two = quote_two("b/", name_b + (*name_b == '/'));
lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null";
printf("%sdiff --git %s %s%s\n", set, a_one, b_two, reset);
diff --git a/fast-import.c b/fast-import.c
index fd3b117574..1ae125a040 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -133,6 +133,10 @@ Format of STDIN stream:
#define PACK_ID_BITS 16
#define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)
+#ifndef PRIuMAX
+#define PRIuMAX "llu"
+#endif
+
struct object_entry
{
struct object_entry *next;
@@ -475,7 +479,7 @@ static struct object_entry *find_mark(uintmax_t idnum)
oe = s->data.marked[idnum];
}
if (!oe)
- die("mark :%ju not declared", orig_idnum);
+ die("mark :%" PRIuMAX " not declared", orig_idnum);
return oe;
}
@@ -1361,7 +1365,7 @@ static void dump_marks_helper(FILE *f,
} else {
for (k = 0; k < 1024; k++) {
if (m->data.marked[k])
- fprintf(f, ":%ju %s\n", base + k,
+ fprintf(f, ":%" PRIuMAX " %s\n", base + k,
sha1_to_hex(m->data.marked[k]->sha1));
}
}
@@ -1687,7 +1691,7 @@ static void cmd_from(struct branch *b)
unsigned long size;
char *buf;
if (oe->type != OBJ_COMMIT)
- die("Mark :%ju not a commit", idnum);
+ die("Mark :%" PRIuMAX " not a commit", idnum);
hashcpy(b->sha1, oe->sha1);
buf = gfi_unpack_entry(oe, &size);
if (!buf || size < 46)
@@ -1740,7 +1744,7 @@ static struct hash_list *cmd_merge(unsigned int *count)
uintmax_t idnum = strtoumax(from + 1, NULL, 10);
struct object_entry *oe = find_mark(idnum);
if (oe->type != OBJ_COMMIT)
- die("Mark :%ju not a commit", idnum);
+ die("Mark :%" PRIuMAX " not a commit", idnum);
hashcpy(n->sha1, oe->sha1);
} else if (get_sha1(from, n->sha1))
die("Invalid ref name or SHA1 expression: %s", from);
@@ -1884,7 +1888,7 @@ static void cmd_new_tag(void)
from_mark = strtoumax(from + 1, NULL, 10);
oe = find_mark(from_mark);
if (oe->type != OBJ_COMMIT)
- die("Mark :%ju not a commit", from_mark);
+ die("Mark :%" PRIuMAX " not a commit", from_mark);
hashcpy(sha1, oe->sha1);
} else if (!get_sha1(from, sha1)) {
unsigned long size;
@@ -2059,18 +2063,18 @@ int main(int argc, const char **argv)
fprintf(stderr, "%s statistics:\n", argv[0]);
fprintf(stderr, "---------------------------------------------------------------------\n");
- fprintf(stderr, "Alloc'd objects: %10ju\n", alloc_count);
- fprintf(stderr, "Total objects: %10ju (%10ju duplicates )\n", total_count, duplicate_count);
- fprintf(stderr, " blobs : %10ju (%10ju duplicates %10ju deltas)\n", object_count_by_type[OBJ_BLOB], duplicate_count_by_type[OBJ_BLOB], delta_count_by_type[OBJ_BLOB]);
- fprintf(stderr, " trees : %10ju (%10ju duplicates %10ju deltas)\n", object_count_by_type[OBJ_TREE], duplicate_count_by_type[OBJ_TREE], delta_count_by_type[OBJ_TREE]);
- fprintf(stderr, " commits: %10ju (%10ju duplicates %10ju deltas)\n", object_count_by_type[OBJ_COMMIT], duplicate_count_by_type[OBJ_COMMIT], delta_count_by_type[OBJ_COMMIT]);
- fprintf(stderr, " tags : %10ju (%10ju duplicates %10ju deltas)\n", object_count_by_type[OBJ_TAG], duplicate_count_by_type[OBJ_TAG], delta_count_by_type[OBJ_TAG]);
+ fprintf(stderr, "Alloc'd objects: %10" PRIuMAX "\n", alloc_count);
+ fprintf(stderr, "Total objects: %10" PRIuMAX " (%10" PRIuMAX " duplicates )\n", total_count, duplicate_count);
+ fprintf(stderr, " blobs : %10" PRIuMAX " (%10" PRIuMAX " duplicates %10" PRIuMAX " deltas)\n", object_count_by_type[OBJ_BLOB], duplicate_count_by_type[OBJ_BLOB], delta_count_by_type[OBJ_BLOB]);
+ fprintf(stderr, " trees : %10" PRIuMAX " (%10" PRIuMAX " duplicates %10" PRIuMAX " deltas)\n", object_count_by_type[OBJ_TREE], duplicate_count_by_type[OBJ_TREE], delta_count_by_type[OBJ_TREE]);
+ fprintf(stderr, " commits: %10" PRIuMAX " (%10" PRIuMAX " duplicates %10" PRIuMAX " deltas)\n", object_count_by_type[OBJ_COMMIT], duplicate_count_by_type[OBJ_COMMIT], delta_count_by_type[OBJ_COMMIT]);
+ fprintf(stderr, " tags : %10" PRIuMAX " (%10" PRIuMAX " duplicates %10" PRIuMAX " deltas)\n", object_count_by_type[OBJ_TAG], duplicate_count_by_type[OBJ_TAG], delta_count_by_type[OBJ_TAG]);
fprintf(stderr, "Total branches: %10lu (%10lu loads )\n", branch_count, branch_load_count);
- fprintf(stderr, " marks: %10ju (%10ju unique )\n", (((uintmax_t)1) << marks->shift) * 1024, marks_set_count);
+ fprintf(stderr, " marks: %10" PRIuMAX " (%10" PRIuMAX " unique )\n", (((uintmax_t)1) << marks->shift) * 1024, marks_set_count);
fprintf(stderr, " atoms: %10u\n", atom_cnt);
- fprintf(stderr, "Memory total: %10ju KiB\n", (total_allocd + alloc_count*sizeof(struct object_entry))/1024);
+ fprintf(stderr, "Memory total: %10" PRIuMAX " KiB\n", (total_allocd + alloc_count*sizeof(struct object_entry))/1024);
fprintf(stderr, " pools: %10lu KiB\n", (unsigned long)(total_allocd/1024));
- fprintf(stderr, " objects: %10ju KiB\n", (alloc_count*sizeof(struct object_entry))/1024);
+ fprintf(stderr, " objects: %10" PRIuMAX " KiB\n", (alloc_count*sizeof(struct object_entry))/1024);
fprintf(stderr, "---------------------------------------------------------------------\n");
pack_report();
fprintf(stderr, "---------------------------------------------------------------------\n");
diff --git a/git-am.sh b/git-am.sh
index 6db9cb503a..2c73d116b2 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -66,7 +66,7 @@ fall_back_3way () {
git-update-index -z --index-info <"$dotest/patch-merge-index-info" &&
GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
git-write-tree >"$dotest/patch-merge-base+" ||
- cannot_fallback "Patch does not record usable index information."
+ cannot_fallback "Repository lacks necessary blobs to fall back on 3-way merge."
echo Using index info to reconstruct a base tree...
if GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
diff --git a/git-commit.sh b/git-commit.sh
index ec506d956f..476f4f18db 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -318,6 +318,10 @@ esac
case "$all,$also" in
t,)
+ if test ! -f "$THIS_INDEX"
+ then
+ die 'nothing to commit (use "git add file1 file2" to include for commit)'
+ fi
save_index &&
(
cd_to_toplevel &&
diff --git a/git-compat-util.h b/git-compat-util.h
index c1bcb001a5..9863cf671f 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -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 \
@@ -136,6 +139,11 @@ extern char *gitstrcasestr(const char *haystack, const char *needle);
extern size_t gitstrlcpy(char *, const char *, size_t);
#endif
+#ifdef NO_STRTOUMAX
+#define strtoumax gitstrtoumax
+extern uintmax_t gitstrtoumax(const char *, char **, int);
+#endif
+
extern void release_pack_memory(size_t);
static inline char* xstrdup(const char *str)
diff --git a/git-gui/.gitignore b/git-gui/.gitignore
index c714d382e8..805ca2e1c7 100644
--- a/git-gui/.gitignore
+++ b/git-gui/.gitignore
@@ -1,3 +1,4 @@
+CREDITS-FILE
GIT-VERSION-FILE
git-citool
git-gui
diff --git a/git-gui/CREDITS-GEN b/git-gui/CREDITS-GEN
new file mode 100755
index 0000000000..d1b0f86355
--- /dev/null
+++ b/git-gui/CREDITS-GEN
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+CF=CREDITS-FILE
+tip=
+
+tree_search ()
+{
+ head=$1
+ tree=$2
+ for p in $(git rev-list --parents --max-count=1 $head 2>/dev/null)
+ do
+ test $tree = $(git rev-parse $p^{tree} 2>/dev/null) &&
+ vn=$(git describe --abbrev=4 $p 2>/dev/null) &&
+ case "$vn" in
+ gitgui-[0-9]*) echo $p; break;;
+ esac
+ done
+}
+
+generate_credits ()
+{
+ tip=$1 &&
+ rm -f "$2" &&
+ git shortlog -n -s $tip | sed 's/: .*$//' >"$2" || exit
+}
+
+# Always use the tarball credits file if found, just
+# in case we are somehow contained in a larger git
+# repository that doesn't actually track our state.
+# (At least one package manager is doing this.)
+#
+# We may be a subproject, so try looking for the merge
+# commit that supplied this directory content if we are
+# not at the toplevel. We probably will always be the
+# second parent in the commit, but we shouldn't rely on
+# that fact.
+#
+
+credits_tmp=/var/tmp/gitgui-credits-$$
+trap 'rm -f "$credits_tmp"' 0
+
+orig="$credits_tmp"
+
+if test -f credits
+then
+ orig=credits
+elif prefix="$(git rev-parse --show-prefix 2>/dev/null)" &&
+ test -n "$prefix" &&
+ head=$(git rev-list --max-count=1 HEAD -- . 2>/dev/null) &&
+ tree=$(git rev-parse --verify "HEAD:$prefix" 2>/dev/null) &&
+ tip=$(tree_search $head $tree) &&
+ test -n "$tip"
+then
+ generate_credits $tip "$orig" || exit
+elif tip="$(git rev-parse --verify HEAD 2>/dev/null)" &&
+ test -n "$tip"
+then
+ generate_credits $tip "$orig" || exit
+else
+ echo "error: Cannot locate authorship information." >&2
+ exit 1
+fi
+
+if test -f "$orig" && cmp -s "$orig" "$CF"
+then
+ : noop
+else
+ rm -f "$CF" &&
+ cat "$orig" >"$CF"
+fi
+
diff --git a/git-gui/GIT-VERSION-GEN b/git-gui/GIT-VERSION-GEN
index 9966126da2..2741c1e14c 100755
--- a/git-gui/GIT-VERSION-GEN
+++ b/git-gui/GIT-VERSION-GEN
@@ -20,6 +20,11 @@ tree_search ()
done
}
+# Always use the tarball version file if found, just
+# in case we are somehow contained in a larger git
+# repository that doesn't actually track our state.
+# (At least one package manager is doing this.)
+#
# We may be a subproject, so try looking for the merge
# commit that supplied this directory content if we are
# not at the toplevel. We probably will always be the
@@ -27,10 +32,13 @@ tree_search ()
# that fact.
#
# If we are at the toplevel or the merge assumption fails
-# try looking for a gitgui-* tag, or fallback onto the
-# distributed version file.
+# try looking for a gitgui-* tag.
-if prefix="$(git rev-parse --show-prefix 2>/dev/null)"
+if test -f version &&
+ VN=$(cat version)
+then
+ : happy
+elif prefix="$(git rev-parse --show-prefix 2>/dev/null)"
test -n "$prefix" &&
head=$(git rev-list --max-count=1 HEAD -- . 2>/dev/null) &&
tree=$(git rev-parse --verify "HEAD:$prefix" 2>/dev/null) &&
@@ -48,9 +56,6 @@ elif VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
esac
then
VN=$(echo "$VN" | sed -e 's/^gitgui-//;s/-/./g');
-elif test -f version
-then
- VN=$(cat version) || VN="$DEF_VER"
else
VN="$DEF_VER"
fi
diff --git a/git-gui/Makefile b/git-gui/Makefile
index fd82d9d16d..66538ba1ad 100644
--- a/git-gui/Makefile
+++ b/git-gui/Makefile
@@ -4,9 +4,8 @@ GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
@$(SHELL_PATH) ./GIT-VERSION-GEN
-include GIT-VERSION-FILE
-SCRIPT_SH = git-gui.sh
GITGUI_BUILT_INS = git-citool
-ALL_PROGRAMS = $(GITGUI_BUILT_INS) $(patsubst %.sh,%,$(SCRIPT_SH))
+ALL_PROGRAMS = git-gui $(GITGUI_BUILT_INS)
ifndef SHELL_PATH
SHELL_PATH = /bin/sh
@@ -24,20 +23,24 @@ DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
-$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
+git-gui: git-gui.sh GIT-VERSION-FILE CREDITS-FILE
rm -f $@ $@+
- sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
+ sed -n \
+ -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-e 's/@@GITGUI_VERSION@@/$(GITGUI_VERSION)/g' \
+ -e '1,/^set gitgui_credits /p' \
$@.sh >$@+
+ cat CREDITS-FILE >>$@+
+ sed -e '1,/^set gitgui_credits /d' $@.sh >>$@+
chmod +x $@+
mv $@+ $@
+CREDITS-FILE: CREDITS-GEN .FORCE-CREDITS-FILE
+ $(SHELL_PATH) ./CREDITS-GEN
+
$(GITGUI_BUILT_INS): git-gui
rm -f $@ && ln git-gui $@
-# These can record GITGUI_VERSION
-$(patsubst %.sh,%,$(SCRIPT_SH)): GIT-VERSION-FILE
-
all:: $(ALL_PROGRAMS)
install: all
@@ -45,12 +48,14 @@ install: all
$(INSTALL) git-gui '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(foreach p,$(GITGUI_BUILT_INS), rm -f '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' && ln '$(DESTDIR_SQ)$(gitexecdir_SQ)/git-gui' '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;)
-dist-version:
+dist-version: CREDITS-FILE
@mkdir -p $(TARDIR)
@echo $(GITGUI_VERSION) > $(TARDIR)/version
+ @cat CREDITS-FILE > $(TARDIR)/credits
clean::
- rm -f $(ALL_PROGRAMS) GIT-VERSION-FILE
+ rm -f $(ALL_PROGRAMS) GIT-VERSION-FILE CREDITS-FILE
.PHONY: all install dist-version clean
.PHONY: .FORCE-GIT-VERSION-FILE
+.PHONY: .FORCE-CREDITS-FILE
diff --git a/git-gui/TODO b/git-gui/TODO
deleted file mode 100644
index b95a137322..0000000000
--- a/git-gui/TODO
+++ /dev/null
@@ -1,44 +0,0 @@
-Items outstanding:
-
- * Add file to .gitignore or info/excludes.
-
- * Populate the pull menu with local branches.
-
- * Make use of the new default merge data stored in repo-config.
-
- * Checkout a different local branch.
-
- * Push any local branch to a remote branch.
-
- * Merge any local branches through a real merge UI.
-
- * Allow user to define keyboard shortcuts for frequently used fetch
- or merge operations. Or maybe just define a keyboard shortcut
- for default fetch/default merge of current branch is enough;
- but I do know a few users who merge a couple of common branches
- also into the same branch so one default isn't quite enough.
-
- * Better organize fetch/push/pull console windows.
-
- * Clone UI (to download a new repository).
-
- * Remotes editor (for .git/config format only).
-
- * Show a shortlog of the last couple of commits in the main window,
- to give the user warm fuzzy feelings that we have their data
- saved. Actually this may be the set of commits not yet in
- the upstream (aka default merge branch remote repository).
-
- * GUI configuration editor for options listed in
- git.git/Documentation/config.txt. Ideally this would
- parse that file and generate the options dialog from
- the documentation itself, and include the help text
- from the documentation as part of the UI somehow.
-
-Known bugs:
-
- * git-gui sometimes just closes on Windows with no error message.
- I'm not sure what the problem is here. I suspect the wish
- process is just terminating due to a segfault or something,
- as the do_quit proc in git-gui doesn't run. It often seems to
- occur while writing a commit message in the buffer. Odd.
diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh
index f5010dd47a..f84ba3382b 100755
--- a/git-gui/git-gui.sh
+++ b/git-gui/git-gui.sh
@@ -4,7 +4,7 @@ exec wish "$0" -- "$@"
set appvers {@@GITGUI_VERSION@@}
set copyright {
-Copyright © 2006, 2007 Shawn Pearce, Paul Mackerras.
+Copyright © 2006, 2007 Shawn Pearce, et. al.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,6 +19,9 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA}
+set gitgui_credits {
+Paul Mackerras
+}
######################################################################
##
@@ -46,7 +49,7 @@ proc gitdir {args} {
proc gitexec {args} {
global _gitexec
if {$_gitexec eq {}} {
- if {[catch {set _gitexec [exec git --exec-path]} err]} {
+ if {[catch {set _gitexec [git --exec-path]} err]} {
error "Git not installed?\n\n$err"
}
}
@@ -202,14 +205,14 @@ proc save_config {} {
set value $global_config_new($name)
if {$value ne $global_config($name)} {
if {$value eq $default_config($name)} {
- catch {exec git config --global --unset $name}
+ catch {git config --global --unset $name}
} else {
regsub -all "\[{}\]" $value {"} value
- exec git config --global $name $value
+ git config --global $name $value
}
set global_config($name) $value
if {$value eq $repo_config($name)} {
- catch {exec git config --unset $name}
+ catch {git config --unset $name}
set repo_config($name) $value
}
}
@@ -219,16 +222,24 @@ proc save_config {} {
set value $repo_config_new($name)
if {$value ne $repo_config($name)} {
if {$value eq $global_config($name)} {
- catch {exec git config --unset $name}
+ catch {git config --unset $name}
} else {
regsub -all "\[{}\]" $value {"} value
- exec git config $name $value
+ git config $name $value
}
set repo_config($name) $value
}
}
}
+######################################################################
+##
+## handy utils
+
+proc git {args} {
+ return [eval exec git $args]
+}
+
proc error_popup {msg} {
set title [appname]
if {[reponame] ne {}} {
@@ -289,10 +300,42 @@ proc ask_popup {msg} {
######################################################################
##
+## version check
+
+set req_maj 1
+set req_min 5
+
+if {[catch {set v [git --version]} err]} {
+ catch {wm withdraw .}
+ error_popup "Cannot determine Git version:
+
+$err
+
+[appname] requires Git $req_maj.$req_min or later."
+ exit 1
+}
+if {[regexp {^git version (\d+)\.(\d+)} $v _junk act_maj act_min]} {
+ if {$act_maj < $req_maj
+ || ($act_maj == $req_maj && $act_min < $req_min)} {
+ catch {wm withdraw .}
+ error_popup "[appname] requires Git $req_maj.$req_min or later.
+
+You are using $v."
+ exit 1
+ }
+} else {
+ catch {wm withdraw .}
+ error_popup "Cannot parse Git version string:\n\n$v"
+ exit 1
+}
+unset -nocomplain v _junk act_maj act_min req_maj req_min
+
+######################################################################
+##
## repository setup
if { [catch {set _gitdir $env(GIT_DIR)}]
- && [catch {set _gitdir [exec git rev-parse --git-dir]} err]} {
+ && [catch {set _gitdir [git rev-parse --git-dir]} err]} {
catch {wm withdraw .}
error_popup "Cannot find the git directory:\n\n$err"
exit 1
@@ -321,6 +364,24 @@ set _reponame [lindex [file split \
######################################################################
##
+## global init
+
+set current_diff_path {}
+set current_diff_side {}
+set diff_actions [list]
+set ui_status_value {Initializing...}
+
+set HEAD {}
+set PARENT {}
+set MERGE_HEAD [list]
+set commit_type {}
+set empty_tree {}
+set current_branch {}
+set current_diff_path {}
+set selected_commit_type new
+
+######################################################################
+##
## task management
set rescan_active 0
@@ -365,7 +426,7 @@ proc repository_state {ctvar hdvar mhvar} {
set mh [list]
- if {[catch {set current_branch [exec git symbolic-ref HEAD]}]} {
+ if {[catch {set current_branch [git symbolic-ref HEAD]}]} {
set current_branch {}
} else {
regsub ^refs/((heads|tags|remotes)/)? \
@@ -374,7 +435,7 @@ proc repository_state {ctvar hdvar mhvar} {
current_branch
}
- if {[catch {set hd [exec git rev-parse --verify HEAD]}]} {
+ if {[catch {set hd [git rev-parse --verify HEAD]}]} {
set hd {}
set ct initial
return
@@ -402,7 +463,7 @@ proc PARENT {} {
return $p
}
if {$empty_tree eq {}} {
- set empty_tree [exec git mktree << {}]
+ set empty_tree [git mktree << {}]
}
return $empty_tree
}
@@ -642,8 +703,9 @@ proc reshow_diff {} {
global current_diff_path current_diff_side
set p $current_diff_path
- if {$p eq {}
- || $current_diff_side eq {}
+ if {$p eq {}} {
+ # No diff is being shown.
+ } elseif {$current_diff_side eq {}
|| [catch {set s $file_states($p)}]
|| [lsearch -sorted -exact $file_lists($current_diff_side) $p] == -1} {
clear_diff
@@ -1042,7 +1104,7 @@ proc committer_ident {} {
global GIT_COMMITTER_IDENT
if {$GIT_COMMITTER_IDENT eq {}} {
- if {[catch {set me [exec git var GIT_COMMITTER_IDENT]} err]} {
+ if {[catch {set me [git var GIT_COMMITTER_IDENT]} err]} {
error_popup "Unable to obtain your identity:\n\n$err"
return {}
}
@@ -1256,14 +1318,6 @@ proc commit_committree {fd_wt curHEAD msg} {
return
}
- # -- Make sure our current branch exists.
- #
- if {$commit_type eq {initial}} {
- lappend all_heads $current_branch
- set all_heads [lsort -unique $all_heads]
- populate_branch_menu
- }
-
# -- Cleanup after ourselves.
#
catch {file delete $msg_p}
@@ -1275,7 +1329,7 @@ proc commit_committree {fd_wt curHEAD msg} {
# -- Let rerere do its thing.
#
if {[file isdirectory [gitdir rr-cache]]} {
- catch {exec git rerere}
+ catch {git rerere}
}
# -- Run the post-commit hook.
@@ -1299,6 +1353,14 @@ proc commit_committree {fd_wt curHEAD msg} {
if {[is_enabled singlecommit]} do_quit
+ # -- Make sure our current branch exists.
+ #
+ if {$commit_type eq {initial}} {
+ lappend all_heads $current_branch
+ set all_heads [lsort -unique $all_heads]
+ populate_branch_menu
+ }
+
# -- Update in memory status
#
set selected_commit_type new
@@ -1876,11 +1938,24 @@ proc all_tracking_branches {} {
return [lsort -unique $all_trackings]
}
+proc load_all_tags {} {
+ set all_tags [list]
+ set fd [open "| git for-each-ref --format=%(refname) refs/tags" r]
+ while {[gets $fd line] > 0} {
+ if {![regsub ^refs/tags/ $line {} name]} continue
+ lappend all_tags $name
+ }
+ close $fd
+
+ return [lsort $all_tags]
+}
+
proc do_create_branch_action {w} {
global all_heads null_sha1 repo_config
global create_branch_checkout create_branch_revtype
global create_branch_head create_branch_trackinghead
global create_branch_name create_branch_revexp
+ global create_branch_tag
set newbranch $create_branch_name
if {$newbranch eq {}
@@ -1894,7 +1969,7 @@ proc do_create_branch_action {w} {
focus $w.desc.name_t
return
}
- if {![catch {exec git show-ref --verify -- "refs/heads/$newbranch"}]} {
+ if {![catch {git show-ref --verify -- "refs/heads/$newbranch"}]} {
tk_messageBox \
-icon error \
-type ok \
@@ -1904,7 +1979,7 @@ proc do_create_branch_action {w} {
focus $w.desc.name_t
return
}
- if {[catch {exec git check-ref-format "heads/$newbranch"}]} {
+ if {[catch {git check-ref-format "heads/$newbranch"}]} {
tk_messageBox \
-icon error \
-type ok \
@@ -1919,9 +1994,10 @@ proc do_create_branch_action {w} {
switch -- $create_branch_revtype {
head {set rev $create_branch_head}
tracking {set rev $create_branch_trackinghead}
+ tag {set rev $create_branch_tag}
expression {set rev $create_branch_revexp}
}
- if {[catch {set cmt [exec git rev-parse --verify "${rev}^0"]}]} {
+ if {[catch {set cmt [git rev-parse --verify "${rev}^0"]}]} {
tk_messageBox \
-icon error \
-type ok \
@@ -1964,6 +2040,8 @@ trace add variable create_branch_head write \
[list radio_selector create_branch_revtype head]
trace add variable create_branch_trackinghead write \
[list radio_selector create_branch_revtype tracking]
+trace add variable create_branch_tag write \
+ [list radio_selector create_branch_revtype tag]
trace add variable delete_branch_head write \
[list radio_selector delete_branch_checktype head]
@@ -1975,6 +2053,7 @@ proc do_create_branch {} {
global create_branch_checkout create_branch_revtype
global create_branch_head create_branch_trackinghead
global create_branch_name create_branch_revexp
+ global create_branch_tag
set w .branch_editor
toplevel $w
@@ -2038,6 +2117,19 @@ proc do_create_branch {} {
$all_trackings
grid $w.from.tracking_r $w.from.tracking_m -sticky w
}
+ set all_tags [load_all_tags]
+ if {$all_tags ne {}} {
+ set create_branch_tag [lindex $all_tags 0]
+ radiobutton $w.from.tag_r \
+ -text {Tag:} \
+ -value tag \
+ -variable create_branch_revtype \
+ -font font_ui
+ eval tk_optionMenu $w.from.tag_m \
+ create_branch_tag \
+ $all_tags
+ grid $w.from.tag_r $w.from.tag_m -sticky w
+ }
radiobutton $w.from.exp_r \
-text {Revision Expression:} \
-value expression \
@@ -2100,7 +2192,7 @@ proc do_delete_branch_action {w} {
}
if {$check_rev eq {:none}} {
set check_cmt {}
- } elseif {[catch {set check_cmt [exec git rev-parse --verify "${check_rev}^0"]}]} {
+ } elseif {[catch {set check_cmt [git rev-parse --verify "${check_rev}^0"]}]} {
tk_messageBox \
-icon error \
-type ok \
@@ -2114,10 +2206,10 @@ proc do_delete_branch_action {w} {
set not_merged [list]
foreach i [$w.list.l curselection] {
set b [$w.list.l get $i]
- if {[catch {set o [exec git rev-parse --verify $b]}]} continue
+ if {[catch {set o [git rev-parse --verify $b]}]} continue
if {$check_cmt ne {}} {
if {$b eq $check_rev} continue
- if {[catch {set m [exec git merge-base $o $check_cmt]}]} continue
+ if {[catch {set m [git merge-base $o $check_cmt]}]} continue
if {$o ne $m} {
lappend not_merged $b
continue
@@ -2155,7 +2247,7 @@ Delete the selected branches?}
foreach i $to_delete {
set b [lindex $i 0]
set o [lindex $i 1]
- if {[catch {exec git update-ref -d "refs/heads/$b" $o} err]} {
+ if {[catch {git update-ref -d "refs/heads/$b" $o} err]} {
append failed " - $b: $err\n"
} else {
set x [lsearch -sorted -exact $all_heads $b]
@@ -2366,7 +2458,7 @@ Staying on branch '$current_branch'."
# here, it Just Works(tm). If it doesn't we are in some really ugly
# state that is difficult to recover from within git-gui.
#
- if {[catch {exec git symbolic-ref HEAD "refs/heads/$new_branch"} err]} {
+ if {[catch {git symbolic-ref HEAD "refs/heads/$new_branch"} err]} {
error_popup "Failed to set current branch.
This working directory is only partially switched.
@@ -2876,14 +2968,16 @@ proc do_local_merge {} {
pack $w.source -fill both -expand 1 -pady 5 -padx 5
set cmd [list git for-each-ref]
- lappend cmd {--format=%(objectname) %(refname)}
+ lappend cmd {--format=%(objectname) %(*objectname) %(refname)}
lappend cmd refs/heads
lappend cmd refs/remotes
+ lappend cmd refs/tags
set fr_fd [open "| $cmd" r]
fconfigure $fr_fd -translation binary
while {[gets $fr_fd line] > 0} {
set line [split $line { }]
- set sha1([lindex $line 0]) [lindex $line 1]
+ set sha1([lindex $line 0]) [lindex $line 2]
+ set sha1([lindex $line 1]) [lindex $line 2]
}
close $fr_fd
@@ -2891,7 +2985,7 @@ proc do_local_merge {} {
set fr_fd [open "| git rev-list --all --not HEAD"]
while {[gets $fr_fd line] > 0} {
if {[catch {set ref $sha1($line)}]} continue
- regsub ^refs/(heads|remotes)/ $ref {} ref
+ regsub ^refs/(heads|remotes|tags)/ $ref {} ref
lappend to_show $ref
}
close $fr_fd
@@ -2972,7 +3066,14 @@ proc new_browser {commit} {
global next_browser_id cursor_ptr M1B
global browser_commit browser_status browser_stack browser_path browser_busy
- set w .browser[incr next_browser_id]
+ if {[winfo ismapped .]} {
+ set w .browser[incr next_browser_id]
+ set tl $w
+ toplevel $w
+ } else {
+ set w {}
+ set tl .
+ }
set w_list $w.list.l
set browser_commit($w_list) $commit
set browser_status($w_list) {Starting...}
@@ -2980,7 +3081,6 @@ proc new_browser {commit} {
set browser_path($w_list) $browser_commit($w_list):
set browser_busy($w_list) 1
- toplevel $w
label $w.path -textvariable browser_path($w_list) \
-anchor w \
-justify left \
@@ -3030,8 +3130,8 @@ proc new_browser {commit} {
bind $w_list <Left> break
bind $w_list <Right> break
- bind $w <Visibility> "focus $w"
- bind $w <Destroy> "
+ bind $tl <Visibility> "focus $w"
+ bind $tl <Destroy> "
array unset browser_buffer $w_list
array unset browser_files $w_list
array unset browser_status $w_list
@@ -3040,7 +3140,7 @@ proc new_browser {commit} {
array unset browser_commit $w_list
array unset browser_busy $w_list
"
- wm title $w "[appname] ([reponame]): File Browser"
+ wm title $tl "[appname] ([reponame]): File Browser"
ls_tree $w_list $browser_commit($w_list) {}
}
@@ -4161,7 +4261,7 @@ proc do_quit {} {
set rc_geometry {}
}
if {$cfg_geometry ne $rc_geometry} {
- catch {exec git config gui.geometry $cfg_geometry}
+ catch {git config gui.geometry $cfg_geometry}
}
}
@@ -4380,6 +4480,61 @@ proc do_commit {} {
commit_tree
}
+proc do_credits {} {
+ global gitgui_credits
+
+ set w .credits_dialog
+
+ toplevel $w
+ wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
+
+ label $w.header -text {git-gui Contributors} -font font_uibold
+ pack $w.header -side top -fill x
+
+ frame $w.buttons
+ button $w.buttons.close -text {Close} \
+ -font font_ui \
+ -command [list destroy $w]
+ pack $w.buttons.close -side right
+ pack $w.buttons -side bottom -fill x -pady 10 -padx 10
+
+ frame $w.credits
+ text $w.credits.t \
+ -background [$w.header cget -background] \
+ -yscrollcommand [list $w.credits.sby set] \
+ -width 20 \
+ -height 10 \
+ -wrap none \
+ -borderwidth 1 \
+ -relief solid \
+ -padx 5 -pady 5 \
+ -font font_ui
+ scrollbar $w.credits.sby -command [list $w.credits.t yview]
+ pack $w.credits.sby -side right -fill y
+ pack $w.credits.t -fill both -expand 1
+ pack $w.credits -side top -fill both -expand 1 -padx 5 -pady 5
+
+ label $w.desc \
+ -text "All portions are copyrighted by their respective authors
+and are distributed under the GNU General Public License." \
+ -padx 5 -pady 5 \
+ -justify left \
+ -anchor w \
+ -borderwidth 1 \
+ -relief solid \
+ -font font_ui
+ pack $w.desc -side top -fill x -padx 5 -pady 5
+
+ $w.credits.t insert end "[string trim $gitgui_credits]\n"
+ $w.credits.t conf -state disabled
+ $w.credits.t see 1.0
+
+ bind $w <Visibility> "grab $w; focus $w"
+ bind $w <Key-Escape> [list destroy $w]
+ wm title $w [$w.header cget -text]
+ tkwait window $w
+}
+
proc do_about {} {
global appvers copyright
global tcl_patchLevel tk_patchLevel
@@ -4396,11 +4551,15 @@ proc do_about {} {
button $w.buttons.close -text {Close} \
-font font_ui \
-command [list destroy $w]
+ button $w.buttons.credits -text {Contributors} \
+ -font font_ui \
+ -command do_credits
+ pack $w.buttons.credits -side left
pack $w.buttons.close -side right
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
label $w.desc \
- -text "[appname] - a commit creation tool for Git.
+ -text "git-gui - a graphical user interface for Git.
$copyright" \
-padx 5 -pady 5 \
-justify left \
@@ -4411,8 +4570,8 @@ $copyright" \
pack $w.desc -side top -fill x -padx 5 -pady 5
set v {}
- append v "[appname] version $appvers\n"
- append v "[exec git version]\n"
+ append v "git-gui version $appvers\n"
+ append v "[git version]\n"
append v "\n"
if {$tcl_patchLevel eq $tk_patchLevel} {
append v "Tcl/Tk version $tcl_patchLevel"
@@ -4471,7 +4630,7 @@ proc do_options {} {
toplevel $w
wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
- label $w.header -text "[appname] Options" \
+ label $w.header -text "Options" \
-font font_uibold
pack $w.header -side top -fill x
@@ -4945,6 +5104,9 @@ enable_option branch
enable_option transport
switch -- $subcommand {
+--version -
+version -
+browser -
blame {
disable_option multicommit
disable_option branch
@@ -5177,7 +5339,7 @@ if {[is_MacOSX]} {
.mbar.apple add command -label "About [appname]" \
-command do_about \
-font font_ui
- .mbar.apple add command -label "[appname] Options..." \
+ .mbar.apple add command -label "Options..." \
-command do_options \
-font font_ui
} else {
@@ -5236,7 +5398,7 @@ set doc_path [file dirname [gitexec]]
set doc_path [file join $doc_path Documentation index.html]
if {[is_Cygwin]} {
- set doc_path [exec cygpath --windows $doc_path]
+ set doc_path [exec cygpath --mixed $doc_path]
}
if {$browser eq {}} {
@@ -5280,6 +5442,20 @@ bind all <$M1B-Key-W> {destroy [winfo toplevel %W]}
# -- Not a normal commit type invocation? Do that instead!
#
switch -- $subcommand {
+--version -
+version {
+ puts "git-gui version $appvers"
+ exit
+}
+browser {
+ if {[llength $argv] != 1} {
+ puts stderr "usage: $argv0 browser commit"
+ exit 1
+ }
+ set current_branch [lindex $argv 0]
+ new_browser $current_branch
+ return
+}
blame {
if {[llength $argv] != 2} {
puts stderr "usage: $argv0 blame commit path"
@@ -5302,7 +5478,7 @@ gui {
# fall through to setup UI for commits
}
default {
- puts stderr "usage: $argv0 \[{blame|citool}\]"
+ puts stderr "usage: $argv0 \[{blame|browser|citool}\]"
exit 1
}
}
@@ -5552,9 +5728,6 @@ bind_button3 $ui_comm "tk_popup $ctxm %X %Y"
# -- Diff Header
#
-set current_diff_path {}
-set current_diff_side {}
-set diff_actions [list]
proc trace_current_diff_path {varname args} {
global current_diff_path diff_actions file_states
if {$current_diff_path eq {}} {
@@ -5747,7 +5920,6 @@ unset ui_diff_applyhunk
# -- Status Bar
#
-set ui_status_value {Initializing...}
label .status -textvariable ui_status_value \
-anchor w \
-justify left \
@@ -5821,15 +5993,6 @@ unset i
set file_lists($ui_index) [list]
set file_lists($ui_workdir) [list]
-set HEAD {}
-set PARENT {}
-set MERGE_HEAD [list]
-set commit_type {}
-set empty_tree {}
-set current_branch {}
-set current_diff_path {}
-set selected_commit_type new
-
wm title . "[appname] ([file normalize [file dirname [gitdir]]])"
focus -force $ui_comm
@@ -5904,7 +6067,7 @@ if {[is_enabled transport]} {
if {[is_enabled multicommit]} {
set object_limit 2000
if {[is_Windows]} {set object_limit 200}
- regexp {^([0-9]+) objects,} [exec git count-objects] _junk objects_current
+ regexp {^([0-9]+) objects,} [git count-objects] _junk objects_current
if {$objects_current >= $object_limit} {
if {[ask_popup \
"This repository currently has $objects_current loose objects.
diff --git a/git-merge.sh b/git-merge.sh
index 04a5eb0f29..498c938c45 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -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/read-cache.c b/read-cache.c
index c54a611877..605b352396 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -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))
diff --git a/sha1_file.c b/sha1_file.c
index 8ad7fad825..2c870314d5 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -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;
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index caaab26c2f..08e035220c 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -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 &&