aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/config.txt15
-rw-r--r--Documentation/cvs-migration.txt3
-rw-r--r--Documentation/diff-options.txt11
-rw-r--r--Documentation/everyday.txt6
-rw-r--r--Documentation/git-checkout.txt2
-rw-r--r--Documentation/git-clone.txt13
-rw-r--r--Documentation/git-filter-branch.txt4
-rw-r--r--Documentation/git-fsck.txt3
-rw-r--r--Documentation/git-gc.txt15
-rw-r--r--Documentation/git-init.txt8
-rw-r--r--Documentation/git-prune.txt20
-rw-r--r--Documentation/git-push.txt23
-rw-r--r--Documentation/git-rev-parse.txt5
-rw-r--r--Documentation/git-svn.txt6
-rw-r--r--Documentation/git-unpack-objects.txt2
-rw-r--r--Documentation/git.txt10
-rw-r--r--Documentation/gitk.txt6
-rw-r--r--Documentation/hooks.txt12
-rw-r--r--Documentation/user-manual.txt17
-rw-r--r--INSTALL4
-rw-r--r--archive.c4
-rw-r--r--attr.c4
-rw-r--r--builtin-checkout.c4
-rw-r--r--builtin-commit.c2
-rw-r--r--builtin-fetch-pack.c8
-rw-r--r--builtin-fetch.c8
-rw-r--r--builtin-init-db.c11
-rw-r--r--builtin-log.c1
-rw-r--r--builtin-remote.c1
-rw-r--r--builtin-rev-parse.c22
-rw-r--r--cache-tree.c7
-rw-r--r--cache.h20
-rw-r--r--combine-diff.c23
-rwxr-xr-xcontrib/completion/git-completion.bash17
-rw-r--r--contrib/emacs/git.el11
-rw-r--r--contrib/hooks/post-receive-email3
-rw-r--r--copy.c8
-rw-r--r--diff-lib.c3
-rw-r--r--diff.c1
-rw-r--r--diff.h1
-rwxr-xr-xgit-clone.sh1
-rw-r--r--git-compat-util.h16
-rwxr-xr-xgit-cvsimport.perl2
-rwxr-xr-xgit-svn.perl21
-rw-r--r--git.c2
-rw-r--r--gitweb/INSTALL79
-rw-r--r--gitweb/README50
-rwxr-xr-xgitweb/gitweb.perl6
-rw-r--r--imap-send.c7
-rw-r--r--log-tree.c30
-rw-r--r--log-tree.h2
-rw-r--r--pack-write.c8
-rw-r--r--path.c38
-rw-r--r--pkt-line.c15
-rw-r--r--refs.c3
-rw-r--r--remote.c32
-rw-r--r--setup.c60
-rw-r--r--sha1_file.c14
-rw-r--r--sha1_name.c7
-rwxr-xr-xt/t0003-attributes.sh8
-rwxr-xr-xt/t0004-unwritable.sh67
-rwxr-xr-xt/t1301-shared-repo.sh50
-rwxr-xr-xt/t2002-checkout-cache-u.sh4
-rwxr-xr-xt/t5505-remote.sh10
-rwxr-xr-xt/t5516-fetch-push.sh54
-rwxr-xr-xt/t5601-clone.sh26
-rw-r--r--write_or_die.c4
67 files changed, 670 insertions, 290 deletions
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 03f1c3f21..00f089fee 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -234,7 +234,13 @@ core.worktree::
used in combination with repositories found automatically in
a .git directory (i.e. $GIT_DIR is not set).
This can be overridden by the GIT_WORK_TREE environment
- variable and the '--work-tree' command line option.
+ variable and the '--work-tree' command line option. It can be
+ a absolute path or relative path to the directory specified by
+ --git-dir or GIT_DIR.
+ Note: If --git-dir or GIT_DIR are specified but none of
+ --work-tree, GIT_WORK_TREE and core.worktree is specified,
+ the current working directory is regarded as the top directory
+ of your working tree.
core.logAllRefUpdates::
Enable the reflog. Updates to a ref <ref> is logged to the file
@@ -261,7 +267,12 @@ core.sharedRepository::
group-writable). When 'all' (or 'world' or 'everybody'), the
repository will be readable by all users, additionally to being
group-shareable. When 'umask' (or 'false'), git will use permissions
- reported by umask(2). See linkgit:git-init[1]. False by default.
+ reported by umask(2). When '0xxx', where '0xxx' is an octal number,
+ files in the repository will have this mode value. '0xxx' will override
+ user's umask value, and thus, users with a safe umask (0077) can use
+ this option. Examples: '0660' is equivalent to 'group'. '0640' is a
+ repository that is group-readable but not group-writable.
+ See linkgit:git-init[1]. False by default.
core.warnAmbiguousRefs::
If true, git will warn you if the ref name you passed it is ambiguous
diff --git a/Documentation/cvs-migration.txt b/Documentation/cvs-migration.txt
index ea9890022..00f2e36b2 100644
--- a/Documentation/cvs-migration.txt
+++ b/Documentation/cvs-migration.txt
@@ -8,7 +8,8 @@ designating a single shared repository which people can synchronize with;
this document explains how to do that.
Some basic familiarity with git is required. This
-link:tutorial.html[tutorial introduction to git] should be sufficient.
+link:tutorial.html[tutorial introduction to git] and the
+link:glossary.html[git glossary] should be sufficient.
Developing against a shared repository
--------------------------------------
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 8dc5b001c..13234fa28 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -58,6 +58,14 @@ endif::git-format-patch[]
number of modified files, as well as number of added and deleted
lines.
+--dirstat[=limit]::
+ Output only the sub-directories that are impacted by a diff,
+ and to what degree they are impacted. You can override the
+ default cut-off in percent (3) by "--dirstat=limit". If you
+ want to enable "cumulative" directory statistics, you can use
+ the "--cumulative" flag, which adds up percentages recursively
+ even when they have been already reported for a sub-directory.
+
--summary::
Output a condensed summary of extended header information
such as creations, renames and mode changes.
@@ -75,7 +83,8 @@ endif::git-format-patch[]
Show only names of changed files.
--name-status::
- Show only names and status of changed files.
+ Show only names and status of changed files. See the description
+ of the `--diff-filter` option on what the status letters mean.
--color::
Show colored diff.
diff --git a/Documentation/everyday.txt b/Documentation/everyday.txt
index fdbd15a18..e598cdda4 100644
--- a/Documentation/everyday.txt
+++ b/Documentation/everyday.txt
@@ -48,14 +48,12 @@ $ git gc <3>
repository health reasonably well.
<2> check how many loose objects there are and how much
disk space is wasted by not repacking.
-<3> repacks the local repository and performs other housekeeping tasks. Running
-without `--prune` is a safe operation even while other ones are in progress.
+<3> repacks the local repository and performs other housekeeping tasks.
Repack a small project into single pack.::
+
------------
$ git gc <1>
-$ git gc --prune
------------
+
<1> pack all the objects reachable from the refs into one pack,
@@ -182,7 +180,7 @@ $ git pull <3>
$ git log -p ORIG_HEAD.. arch/i386 include/asm-i386 <4>
$ git pull git://git.kernel.org/pub/.../jgarzik/libata-dev.git ALL <5>
$ git reset --hard ORIG_HEAD <6>
-$ git gc --prune <7>
+$ git gc <7>
$ git fetch --tags <8>
------------
+
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index e11cddbfc..a644173e1 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -47,7 +47,7 @@ OPTIONS
by linkgit:git-check-ref-format[1]. Some of these checks
may restrict the characters allowed in a branch name.
---track::
+-t, --track::
When creating a new branch, set up configuration so that git-pull
will automatically retrieve data from the start point, which must be
a branch. Use this if you always pull from the same upstream branch
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 975824301..9b564420c 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -65,10 +65,13 @@ OPTIONS
+
*NOTE*: this is a possibly dangerous operation; do *not* use
it unless you understand what it does. If you clone your
-repository using this option, then delete branches in the
-source repository and then run linkgit:git-gc[1] using the
-'--prune' option in the source repository, it may remove
-objects which are referenced by the cloned repository.
+repository using this option and then delete branches (or use any
+other git command that makes any existing commit unreferenced) in the
+source repository, some objects may become unreferenced (or dangling).
+These objects may be removed by normal git operations (such as git-commit[1])
+which automatically call git-gc[1]. If these objects are removed and
+were referenced by the cloned repository, then the cloned repository
+will become corrupt.
@@ -79,6 +82,8 @@ objects which are referenced by the cloned repository.
an already existing repository as an alternate will
require fewer objects to be copied from the repository
being cloned, reducing network and local storage costs.
++
+*NOTE*: see NOTE to --shared option.
--quiet::
-q::
diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt
index 2a78549be..6454e49bf 100644
--- a/Documentation/git-filter-branch.txt
+++ b/Documentation/git-filter-branch.txt
@@ -243,12 +243,12 @@ committed a merge between P1 and P2, it will be propagated properly
and all children of the merge will become merge commits with P1,P2
as their parents instead of the merge commit.
-You can rewrite the commit log messages using `--message-filter`. For
+You can rewrite the commit log messages using `--msg-filter`. For
example, `git-svn-id` strings in a repository created by `git-svn` can
be removed this way:
-------------------------------------------------------
-git filter-branch --message-filter '
+git filter-branch --msg-filter '
sed -e "/^git-svn-id:/d"
'
-------------------------------------------------------
diff --git a/Documentation/git-fsck.txt b/Documentation/git-fsck.txt
index f16cb9861..4cc26fb74 100644
--- a/Documentation/git-fsck.txt
+++ b/Documentation/git-fsck.txt
@@ -22,7 +22,8 @@ OPTIONS
An object to treat as the head of an unreachability trace.
+
If no objects are given, git-fsck defaults to using the
-index file and all SHA1 references in .git/refs/* as heads.
+index file, all SHA1 references in .git/refs/*, and all reflogs (unless
+--no-reflogs is given) as heads.
--unreachable::
Print out objects that exist but that aren't readable from any
diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt
index d424a4ecb..b6b5ce151 100644
--- a/Documentation/git-gc.txt
+++ b/Documentation/git-gc.txt
@@ -104,6 +104,21 @@ The optional configuration variable 'gc.pruneExpire' controls how old
the unreferenced loose objects have to be before they are pruned. The
default is "2 weeks ago".
+
+Notes
+-----
+
+git-gc tries very hard to be safe about the garbage it collects. In
+particular, it will keep not only objects referenced by your current set
+of branches and tags, but also objects referenced by the index, remote
+tracking branches, refs saved by linkgit:git-filter-branch[1] in
+refs/original/, or reflogs (which may references commits in branches
+that were later amended or rewound).
+
+If you are expecting some objects to be collected and they aren't, check
+all of those locations and decide whether it makes sense in your case to
+remove those references.
+
See Also
--------
linkgit:git-prune[1]
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 62914da97..b17ae8485 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -31,7 +31,7 @@ structure, some suggested "exclude patterns", and copies of non-executing
"hook" files. The suggested patterns and hook files are all modifiable and
extensible.
---shared[={false|true|umask|group|all|world|everybody}]::
+--shared[={false|true|umask|group|all|world|everybody|0xxx}]::
Specify that the git repository is to be shared amongst several users. This
allows users belonging to the same group to push into that
@@ -52,6 +52,12 @@ is given:
- 'all' (or 'world' or 'everybody'): Same as 'group', but make the repository
readable by all users.
+ - '0xxx': '0xxx' is an octal number and each file will have mode '0xxx'
+ Any option except 'umask' can be set using this option. '0xxx' will
+ override users umask(2) value, and thus, users with a safe umask (0077)
+ can use this option. '0640' will create a repository which is group-readable
+ but not writable. '0660' is equivalent to 'group'.
+
By default, the configuration flag receive.denyNonFastForwards is enabled
in shared repositories, so that you cannot force a non fast-forwarding push
into it.
diff --git a/Documentation/git-prune.txt b/Documentation/git-prune.txt
index f151cff5d..f92bb8cfa 100644
--- a/Documentation/git-prune.txt
+++ b/Documentation/git-prune.txt
@@ -13,6 +13,9 @@ SYNOPSIS
DESCRIPTION
-----------
+NOTE: In most cases, users should run linkgit:git-gc[1], which calls
+git-prune. See the section "NOTES", below.
+
This runs `git-fsck --unreachable` using all the refs
available in `$GIT_DIR/refs`, optionally with additional set of
objects specified on the command line, and prunes all
@@ -50,6 +53,23 @@ borrows from your repository via its
$ git prune $(cd ../another && $(git-rev-parse --all))
------------
+Notes
+-----
+
+In most cases, users will not need to call git-prune directly, but
+should instead call linkgit:git-gc[1], which handles pruning along with
+many other housekeeping tasks.
+
+For a description of which objects are considered for pruning, see
+git-fsck's --unreachable option.
+
+See Also
+--------
+
+linkgit:git-fsck[1],
+linkgit:git-gc[1],
+linkgit:git-reflog[1]
+
Author
------
Written by Linus Torvalds <torvalds@osdl.org>
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index dc1d4b0b6..f06d94e31 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -35,14 +35,15 @@ OPTIONS
by the source ref, followed by a colon `:`, followed by
the destination ref.
+
-The <src> side can be an
-arbitrary "SHA1 expression" that can be used as an
-argument to `git-cat-file -t`. E.g. `master~4` (push
-four parents before the current master head).
+The <src> side represents the source branch (or arbitrary
+"SHA1 expression", such as `master~4` (four parents before the
+tip of `master` branch); see linkgit:git-rev-parse[1]) that you
+want to push. The <dst> side represents the destination location.
+
The local ref that matches <src> is used
-to fast forward the remote ref that matches <dst>. If
-the optional plus `+` is used, the remote ref is updated
+to fast forward the remote ref that matches <dst> (or, if no <dst> was
+specified, the same ref that <src> referred to locally). If
+the optional leading plus `+` is used, the remote ref is updated
even if it does not result in a fast forward update.
+
Note: If no explicit refspec is found, (that is neither
@@ -167,7 +168,8 @@ git push origin master::
Find a ref that matches `master` in the source repository
(most likely, it would find `refs/heads/master`), and update
the same ref (e.g. `refs/heads/master`) in `origin` repository
- with it.
+ with it. If `master` did not exist remotely, it would be
+ created.
git push origin :experimental::
Find a ref that matches `experimental` in the `origin` repository
@@ -181,9 +183,10 @@ git push origin master:satellite/master::
git push origin master:refs/heads/experimental::
Create the branch `experimental` in the `origin` repository
- by copying the current `master` branch. This form is usually
- needed to create a new branch in the remote repository as
- there is no `experimental` branch to match.
+ by copying the current `master` branch. This form is only
+ needed to create a new branch or tag in the remote repository when
+ the local name and the remote name are different; otherwise,
+ the ref name on its own will work.
Author
------
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 6513c2efe..110e7ba71 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -52,6 +52,11 @@ OPTIONS
The parameter given must be usable as a single, valid
object name. Otherwise barf and abort.
+-q, --quiet::
+ Only meaningful in `--verify` mode. Do not output an error
+ message if the first argument is not a valid object name;
+ instead exit with non-zero status silently.
+
--sq::
Usually the output is made one line per flag and
parameter. This option makes output a single line,
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index bec9accc8..f4ba1056f 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -188,6 +188,12 @@ All arguments are passed directly to `git blame'.
commit. All merging is assumed to have taken place
independently of git-svn functions.
+'create-ignore'::
+
+ Recursively finds the svn:ignore property on directories and
+ creates matching .gitignore files. The resulting files are staged to
+ be committed, but are not committed.
+
'show-ignore'::
Recursively finds and lists the svn:ignore property on
directories. The output is suitable for appending to
diff --git a/Documentation/git-unpack-objects.txt b/Documentation/git-unpack-objects.txt
index 3697896a0..50947c50d 100644
--- a/Documentation/git-unpack-objects.txt
+++ b/Documentation/git-unpack-objects.txt
@@ -8,7 +8,7 @@ git-unpack-objects - Unpack objects from a packed archive
SYNOPSIS
--------
-'git-unpack-objects' [-n] [-q] [-r] <pack-file
+'git-unpack-objects' [-n] [-q] [-r] [--strict] <pack-file
DESCRIPTION
diff --git a/Documentation/git.txt b/Documentation/git.txt
index a070e078e..6f445b1e3 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -143,7 +143,8 @@ help ...'.
--git-dir=<path>::
Set the path to the repository. This can also be controlled by
- setting the GIT_DIR environment variable.
+ setting the GIT_DIR environment variable. It can be an absolute
+ path or relative path to current working directory.
--work-tree=<path>::
Set the path to the working tree. The value will not be
@@ -151,7 +152,12 @@ help ...'.
a .git directory (i.e. $GIT_DIR is not set).
This can also be controlled by setting the GIT_WORK_TREE
environment variable and the core.worktree configuration
- variable.
+ variable. It can be an absolute path or relative path to
+ the directory specified by --git-dir or GIT_DIR.
+ Note: If --git-dir or GIT_DIR are specified but none of
+ --work-tree, GIT_WORK_TREE and core.worktree is specified,
+ the current working directory is regarded as the top directory
+ of your working tree.
--bare::
Treat the repository as a bare repository. If GIT_DIR
diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt
index ed3ba83c5..50d12da89 100644
--- a/Documentation/gitk.txt
+++ b/Documentation/gitk.txt
@@ -41,6 +41,12 @@ frequently used options.
Show all branches.
+--merge::
+
+ After an attempt to merge stops with conflicts, show the commits on
+ the history between two branches (i.e. the HEAD and the MERGE_HEAD)
+ that modify the conflicted files.
+
<revs>::
Limit the revisions to show. This can be either a single revision
diff --git a/Documentation/hooks.txt b/Documentation/hooks.txt
index 44fbe58f2..d89cc2226 100644
--- a/Documentation/hooks.txt
+++ b/Documentation/hooks.txt
@@ -28,10 +28,11 @@ The default 'applypatch-msg' hook, when enabled, runs the
pre-applypatch
--------------
-This hook is invoked by `git-am`. It takes no parameter,
-and is invoked after the patch is applied, but before a commit
-is made. Exiting with non-zero status causes the working tree
-after application of the patch not committed.
+This hook is invoked by `git-am`. It takes no parameter, and is
+invoked after the patch is applied, but before a commit is made.
+
+If it exits with non-zero status, then the working tree will not be
+committed after applying the patch.
It can be used to inspect the current working tree and refuse to
make a commit if it does not pass certain test.
@@ -136,7 +137,8 @@ post-merge
This hook is invoked by `git-merge`, which happens when a `git pull`
is done on a local repository. The hook takes a single parameter, a status
flag specifying whether or not the merge being done was a squash merge.
-This hook cannot affect the outcome of `git-merge`.
+This hook cannot affect the outcome of `git-merge` and is not executed,
+if the merge failed due to conflicts.
This hook can be used in conjunction with a corresponding pre-commit hook to
save and restore any form of metadata associated with the working tree
diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
index 565aeb980..86b91a53e 100644
--- a/Documentation/user-manual.txt
+++ b/Documentation/user-manual.txt
@@ -1548,22 +1548,7 @@ dangling tree b24c2473f1fd3d91352a624795be026d64c8841f
Dangling objects are not a problem. At worst they may take up a little
extra disk space. They can sometimes provide a last-resort method for
-recovering lost work--see <<dangling-objects>> for details. However, if
-you wish, you can remove them with linkgit:git-prune[1] or the `--prune`
-option to linkgit:git-gc[1]:
-
--------------------------------------------------
-$ git gc --prune
--------------------------------------------------
-
-This may be time-consuming. Unlike most other git operations (including
-git-gc when run without any options), it is not safe to prune while
-other git operations are in progress in the same repository.
-
-If linkgit:git-fsck[1] complains about sha1 mismatches or missing
-objects, you may have a much more serious problem; your best option is
-probably restoring from backups. See
-<<recovering-from-repository-corruption>> for a detailed discussion.
+recovering lost work--see <<dangling-objects>> for details.
[[recovering-lost-changes]]
Recovering lost changes
diff --git a/INSTALL b/INSTALL
index 6f3bcb452..d9b425fa7 100644
--- a/INSTALL
+++ b/INSTALL
@@ -38,6 +38,10 @@ Issues of note:
has been actively developed since 1997, and people have moved over to
graphical file managers.
+ NOTE: As of gnuit-4.9.2, the GNU interactive tools package has been
+ renamed. You can compile gnuit with the --disable-transition
+ option and then it will not conflict with git.
+
- You can use git after building but without installing if you
wanted to. Various git commands need to find other git
commands and scripts to do their work, so you would need to
diff --git a/archive.c b/archive.c
index fb159fe59..7a32c19d3 100644
--- a/archive.c
+++ b/archive.c
@@ -16,9 +16,9 @@ static void format_subst(const struct commit *commit,
const char *b, *c;
b = memmem(src, len, "$Format:", 8);
- if (!b || src + len < b + 9)
+ if (!b)
break;
- c = memchr(b + 8, '$', len - 8);
+ c = memchr(b + 8, '$', (src + len) - b - 8);
if (!c)
break;
diff --git a/attr.c b/attr.c
index 64b77b166..1a15fad29 100644
--- a/attr.c
+++ b/attr.c
@@ -546,7 +546,9 @@ static int path_matches(const char *pathname, int pathlen,
(baselen && pathname[baselen] != '/') ||
strncmp(pathname, base, baselen))
return 0;
- return fnmatch(pattern, pathname + baselen + 1, FNM_PATHNAME) == 0;
+ if (baselen != 0)
+ baselen++;
+ return fnmatch(pattern, pathname + baselen, FNM_PATHNAME) == 0;
}
static int fill_one(const char *what, struct match_attr *a, int rem)
diff --git a/builtin-checkout.c b/builtin-checkout.c
index 7deb50483..10ec137cc 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -142,7 +142,7 @@ static void describe_detached_head(char *msg, struct commit *commit)
struct strbuf sb;
strbuf_init(&sb, 0);
parse_commit(commit);
- pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, "", "", 0, 0);
+ pretty_print_commit(CMIT_FMT_ONELINE, commit, &sb, 0, NULL, NULL, 0, 0);
fprintf(stderr, "%s %s... %s\n", msg,
find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV), sb.buf);
strbuf_release(&sb);
@@ -504,7 +504,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
OPT__QUIET(&opts.quiet),
OPT_STRING('b', NULL, &opts.new_branch, "new branch", "branch"),
OPT_BOOLEAN('l', NULL, &opts.new_branch_log, "log for new branch"),
- OPT_SET_INT( 0 , "track", &opts.track, "track",
+ OPT_SET_INT('t', "track", &opts.track, "track",
BRANCH_TRACK_EXPLICIT),
OPT_BOOLEAN('f', NULL, &opts.force, "force"),
OPT_BOOLEAN('m', NULL, &opts.merge, "merge"),
diff --git a/builtin-commit.c b/builtin-commit.c
index b41d4a356..256181a68 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -90,7 +90,7 @@ static struct option builtin_commit_options[] = {
OPT_CALLBACK('m', "message", &message, "MESSAGE", "specify commit message", opt_parse_m),
OPT_STRING('c', "reedit-message", &edit_message, "COMMIT", "reuse and edit message from specified commit "),
OPT_STRING('C', "reuse-message", &use_message, "COMMIT", "reuse message from specified commit"),
- OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by: header"),
+ OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
OPT_STRING('t', "template", &template_file, "FILE", "use specified template file"),
OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"),
diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c
index 65350ca52..c97a42739 100644
--- a/builtin-fetch-pack.c
+++ b/builtin-fetch-pack.c
@@ -117,15 +117,15 @@ static const unsigned char* get_rev(void)
while (commit == NULL) {
unsigned int mark;
- struct commit_list *parents = NULL;
+ struct commit_list *parents;
if (rev_list == NULL || non_common_revs == 0)
return NULL;
commit = rev_list->item;
- if (!(commit->object.parsed))
- if (!parse_commit(commit))
- parents = commit->parents;
+ if (!commit->object.parsed)
+ parse_commit(commit);
+ parents = commit->parents;
commit->object.flags |= POPPED;
if (!(commit->object.flags & COMMON))
diff --git a/builtin-fetch.c b/builtin-fetch.c
index 139a6b10c..167f94803 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -577,8 +577,6 @@ static int do_fetch(struct transport *transport,
free_refs(ref_map);
}
- transport_disconnect(transport);
-
return 0;
}
@@ -599,6 +597,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
int i;
static const char **refs = NULL;
int ref_nr = 0;
+ int exit_code;
/* Record the command line for the reflog */
strbuf_addstr(&default_rla, "fetch");
@@ -652,6 +651,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
signal(SIGINT, unlock_pack_on_signal);
atexit(unlock_pack);
- return do_fetch(transport,
+ exit_code = do_fetch(transport,
parse_fetch_refspec(ref_nr, refs), ref_nr);
+ transport_disconnect(transport);
+ transport = NULL;
+ return exit_code;
}
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 2854868b4..a76f5d347 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -400,9 +400,16 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
char buf[10];
/* We do not spell "group" and such, so that
* the configuration can be read by older version
- * of git.
+ * of git. Note, we use octal numbers for new share modes,
+ * and compatibility values for PERM_GROUP and
+ * PERM_EVERYBODY.
*/
- sprintf(buf, "%d", shared_repository);
+ if (shared_repository == PERM_GROUP)
+ sprintf(buf, "%d", OLD_PERM_GROUP);
+ else if (shared_repository == PERM_EVERYBODY)
+ sprintf(buf, "%d", OLD_PERM_EVERYBODY);
+ else
+ sprintf(buf, "0%o", shared_repository);
git_config_set("core.sharedrepository", buf);
git_config_set("receive.denyNonFastforwards", "true");
}
diff --git a/builtin-log.c b/builtin-log.c
index 1670d0b33..256bbac93 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -770,7 +770,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
rev.diff = 1;
rev.combine_merges = 0;
rev.ignore_merges = 1;
- rev.diffopt.msg_sep = "";
DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
rev.subject_prefix = fmt_patch_subject_prefix;
diff --git a/builtin-remote.c b/builtin-remote.c
index 9d4432bcd..8b63619ef 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -107,6 +107,7 @@ static int add(int argc, const char **argv)
struct path_list_item *item = track.items + i;
strbuf_reset(&buf2);
+ strbuf_addch(&buf2, '+');
if (mirror)
strbuf_addf(&buf2, "refs/%s:refs/%s",
item->path, item->path);
diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index 0351d5443..0e5970732 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -365,9 +365,17 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
return 0;
}
+static void die_no_single_rev(int quiet)
+{
+ if (quiet)
+ exit(1);
+ else
+ die("Needed a single revision");
+}
+
int cmd_rev_parse(int argc, const char **argv, const char *prefix)
{
- int i, as_is = 0, verify = 0;
+ int i, as_is = 0, verify = 0, quiet = 0;
unsigned char sha1[20];
if (argc > 1 && !strcmp("--parseopt", argv[1]))
@@ -432,6 +440,10 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
verify = 1;
continue;
}
+ if (!strcmp(arg, "--quiet") || !strcmp(arg, "-q")) {
+ quiet = 1;
+ continue;
+ }
if (!strcmp(arg, "--short") ||
!prefixcmp(arg, "--short=")) {
filter &= ~(DO_FLAGS|DO_NOREV);
@@ -549,7 +561,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
continue;
}
if (show_flag(arg) && verify)
- die("Needed a single revision");
+ die_no_single_rev(quiet);
continue;
}
@@ -564,15 +576,15 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
show_rev(REVERSED, sha1, arg+1);
continue;
}
+ if (verify)
+ die_no_single_rev(quiet);
as_is = 1;
if (!show_file(arg))
continue;
- if (verify)
- die("Needed a single revision");
verify_filename(prefix, arg);
}
show_default();
if (verify && revs_count != 1)
- die("Needed a single revision");
+ die_no_single_rev(quiet);
return 0;
}
diff --git a/cache-tree.c b/cache-tree.c
index 39da54d1e..73cb34070 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -341,8 +341,11 @@ static int update_one(struct cache_tree *it,
if (dryrun)
hash_sha1_file(buffer.buf, buffer.len, tree_type, it->sha1);
- else
- write_sha1_file(buffer.buf, buffer.len, tree_type, it->sha1);
+ else if (write_sha1_file(buffer.buf, buffer.len, tree_type, it->sha1)) {
+ strbuf_release(&buffer);
+ return -1;
+ }
+
strbuf_release(&buffer);
it->entry_count = i;
#if DEBUG
diff --git a/cache.h b/cache.h
index 50b28fad0..5a28dddec 100644
--- a/cache.h
+++ b/cache.h
@@ -474,10 +474,20 @@ static inline void hashclr(unsigned char *hash)
int git_mkstemp(char *path, size_t n, const char *template);
+/*
+ * NOTE NOTE NOTE!!
+ *
+ * PERM_UMASK, OLD_PERM_GROUP and OLD_PERM_EVERYBODY enumerations must
+ * not be changed. Old repositories have core.sharedrepository written in
+ * numeric format, and therefore these values are preserved for compatibility
+ * reasons.
+ */
enum sharedrepo {
- PERM_UMASK = 0,
- PERM_GROUP,
- PERM_EVERYBODY
+ PERM_UMASK = 0,
+ OLD_PERM_GROUP = 1,
+ OLD_PERM_EVERYBODY = 2,
+ PERM_GROUP = 0660,
+ PERM_EVERYBODY = 0664,
};
int git_config_perm(const char *var, const char *value);
int adjust_shared_perm(const char *path);
@@ -716,8 +726,8 @@ extern const char *git_log_output_encoding;
extern void maybe_flush_or_die(FILE *, const char *);
extern int copy_fd(int ifd, int ofd);
extern int copy_file(const char *dst, const char *src, int mode);
-extern int read_in_full(int fd, void *buf, size_t count);
-extern int write_in_full(int fd, const void *buf, size_t count);
+extern ssize_t read_in_full(int fd, void *buf, size_t count);
+extern ssize_t write_in_full(int fd, const void *buf, size_t count);
extern void write_or_die(int fd, const void *buf, size_t count);
extern int write_or_whine(int fd, const void *buf, size_t count, const char *msg);
extern int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg);
diff --git a/combine-diff.c b/combine-diff.c
index 0e19cbaac..588c58bc5 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -701,7 +701,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
else if (0 <= (fd = open(elem->path, O_RDONLY)) &&
!fstat(fd, &st)) {
size_t len = xsize_t(st.st_size);
- size_t sz = 0;
+ ssize_t done;
int is_file, i;
elem->mode = canon_mode(st.st_mode);
@@ -716,14 +716,13 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
result_size = len;
result = xmalloc(len + 1);
- while (sz < len) {
- ssize_t done = xread(fd, result+sz, len-sz);
- if (done == 0)
- break;
- if (done < 0)
- die("read error '%s'", elem->path);
- sz += done;
- }
+
+ done = read_in_full(fd, result, len);
+ if (done < 0)
+ die("read error '%s'", elem->path);
+ else if (done < len)
+ die("early EOF '%s'", elem->path);
+
result[len] = 0;
}
else {
@@ -798,7 +797,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
int deleted = 0;
if (rev->loginfo && !rev->no_commit_id)
- show_log(rev, opt->msg_sep);
+ show_log(rev);
dump_quoted_path(dense ? "diff --cc " : "diff --combined ",
"", elem->path, c_meta, c_reset);
printf("%sindex ", c_meta);
@@ -881,7 +880,7 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct re
inter_name_termination = 0;
if (rev->loginfo && !rev->no_commit_id)
- show_log(rev, opt->msg_sep);
+ show_log(rev);
if (opt->output_format & DIFF_FORMAT_RAW) {
offset = strlen(COLONS) - num_parent;
@@ -962,7 +961,7 @@ void diff_tree_combined(const unsigned char *sha1,
paths = intersect_paths(paths, i, num_parent);
if (show_log_first && i == 0) {
- show_log(rev, opt->msg_sep);
+ show_log(rev);
if (rev->verbose_header && opt->output_format)
putchar(opt->line_termination);
}
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 4d81963b1..23db664f4 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -152,7 +152,7 @@ __git_heads ()
done
return
fi
- for i in $(git-ls-remote "$1" 2>/dev/null); do
+ for i in $(git ls-remote "$1" 2>/dev/null); do
case "$is_hash,$i" in
y,*) is_hash=n ;;
n,*^{}) is_hash=y ;;
@@ -173,7 +173,7 @@ __git_tags ()
done
return
fi
- for i in $(git-ls-remote "$1" 2>/dev/null); do
+ for i in $(git ls-remote "$1" 2>/dev/null); do
case "$is_hash,$i" in
y,*) is_hash=n ;;
n,*^{}) is_hash=y ;;
@@ -200,7 +200,7 @@ __git_refs ()
done
return
fi
- for i in $(git-ls-remote "$dir" 2>/dev/null); do
+ for i in $(git ls-remote "$dir" 2>/dev/null); do
case "$is_hash,$i" in
y,*) is_hash=n ;;
n,*^{}) is_hash=y ;;
@@ -223,7 +223,7 @@ __git_refs2 ()
__git_refs_remotes ()
{
local cmd i is_hash=y
- for i in $(git-ls-remote "$1" 2>/dev/null); do
+ for i in $(git ls-remote "$1" 2>/dev/null); do
case "$is_hash,$i" in
n,refs/heads/*)
is_hash=y
@@ -641,6 +641,7 @@ _git_diff ()
--ignore-all-space --exit-code --quiet --ext-diff
--no-ext-diff
--no-prefix --src-prefix= --dst-prefix=
+ --base --ours --theirs
"
return
;;
@@ -1052,6 +1053,7 @@ _git_remote ()
local subcommands="add rm show prune update"
local subcommand="$(__git_find_subcommand "$subcommands")"
if [ -z "$subcommand" ]; then
+ __gitcomp "$subcommands"
return
fi
@@ -1344,9 +1346,14 @@ _git ()
_gitk ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
+ local g="$(git rev-parse --git-dir 2>/dev/null)"
+ local merge=""
+ if [ -f $g/MERGE_HEAD ]; then
+ merge="--merge"
+ fi
case "$cur" in
--*)
- __gitcomp "--not --all"
+ __gitcomp "--not --all $merge"
return
;;
esac
diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el
index 4fa853fae..2557a7667 100644
--- a/contrib/emacs/git.el
+++ b/contrib/emacs/git.el
@@ -232,10 +232,8 @@ and returns the process output as a string, or nil if the git failed."
(defun git-run-command-region (buffer start end env &rest args)
"Run a git command with specified buffer region as input."
- (unless (eq 0 (if env
- (git-run-process-region
- buffer start end "env"
- (append (git-get-env-strings env) (list "git") args))
+ (unless (eq 0 (let ((process-environment (append (git-get-env-strings env)
+ process-environment)))
(git-run-process-region
buffer start end "git" args)))
(error "Failed to run \"git %s\":\n%s" (mapconcat (lambda (x) x) args " ") (buffer-string))))
@@ -250,9 +248,8 @@ and returns the process output as a string, or nil if the git failed."
(erase-buffer)
(cd dir)
(setq status
- (if env
- (apply #'call-process "env" nil (list buffer t) nil
- (append (git-get-env-strings env) (list hook-name) args))
+ (let ((process-environment (append (git-get-env-strings env)
+ process-environment)))
(apply #'call-process hook-name nil (list buffer t) nil args))))
(display-message-or-buffer buffer)
(eq 0 status)))))
diff --git a/contrib/hooks/post-receive-email b/contrib/hooks/post-receive-email
index 62a740c48..41368950d 100644
--- a/contrib/hooks/post-receive-email
+++ b/contrib/hooks/post-receive-email
@@ -202,11 +202,12 @@ generate_email_header()
generate_email_footer()
{
+ SPACE=" "
cat <<-EOF
hooks/post-receive
- --
+ --${SPACE}
$projectdesc
EOF
}
diff --git a/copy.c b/copy.c
index afc4fbf41..e54d15ace 100644
--- a/copy.c
+++ b/copy.c
@@ -9,8 +9,7 @@ int copy_fd(int ifd, int ofd)
if (!len)
break;
if (len < 0) {
- int read_error;
- read_error = errno;
+ int read_error = errno;
close(ifd);
return error("copy-fd: read returned %s",
strerror(read_error));
@@ -25,9 +24,10 @@ int copy_fd(int ifd, int ofd)
close(ifd);
return error("copy-fd: write returned 0");
} else {
+ int write_error = errno;
close(ifd);
return error("copy-fd: write returned %s",
- strerror(errno));
+ strerror(write_error));
}
}
}
@@ -48,7 +48,7 @@ int copy_file(const char *dst, const char *src, int mode)
}
status = copy_fd(fdi, fdo);
if (close(fdo) != 0)
- return error("%s: write error: %s", dst, strerror(errno));
+ return error("%s: close error: %s", dst, strerror(errno));
if (!status && adjust_shared_perm(dst))
return -1;
diff --git a/diff-lib.c b/diff-lib.c
index 069e4507a..cfd629da4 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -264,6 +264,9 @@ int setup_diff_no_index(struct rev_info *revs,
DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
break;
}
+ if (nongit && argc != i + 2)
+ die("git diff [--no-index] takes two paths");
+
if (argc != i + 2 || (!is_outside_repo(argv[i + 1], nongit, prefix) &&
!is_outside_repo(argv[i], nongit, prefix)))
return -1;
diff --git a/diff.c b/diff.c
index 3632b552b..e35384b44 100644
--- a/diff.c
+++ b/diff.c
@@ -2220,7 +2220,6 @@ void diff_setup(struct diff_options *options)
options->rename_limit = -1;
options->dirstat_percent = 3;
options->context = 3;
- options->msg_sep = "";
options->change = diff_change;
options->add_remove = diff_addremove;
diff --git a/diff.h b/diff.h
index f2c77391a..1bd94a480 100644
--- a/diff.h
+++ b/diff.h
@@ -88,7 +88,6 @@ struct diff_options {
int abbrev;
const char *prefix;
int prefix_length;
- const char *msg_sep;
const char *stat_sep;
long xdl_opts;
diff --git a/git-clone.sh b/git-clone.sh
index 2636159aa..8c7fc7f63 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -219,6 +219,7 @@ fi
if test -n "$2"
then
dir="$2"
+ test $# = 2 || die "excess parameter to git-clone"
else
# Derive one from the repository name
# Try using "humanish" part of source repo if user didn't specify one
diff --git a/git-compat-util.h b/git-compat-util.h
index a18235e6d..167c3fe63 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -268,6 +268,12 @@ static inline void *xmalloc(size_t size)
return ret;
}
+/*
+ * xmemdupz() allocates (len + 1) bytes of memory, duplicates "len" bytes of
+ * "data" to the allocated memory, zero terminates the allocated memory,
+ * and returns a pointer to the allocated memory. If the allocation fails,
+ * the program dies.
+ */
static inline void *xmemdupz(const void *data, size_t len)
{
char *p = xmalloc(len + 1);
@@ -329,6 +335,11 @@ static inline void *xmmap(void *start, size_t length,
return ret;
}
+/*
+ * xread() is the same a read(), but it automatically restarts read()
+ * operations with a recoverable error (EAGAIN and EINTR). xread()
+ * DOES NOT GUARANTEE that "len" bytes is read even if the data is available.
+ */
static inline ssize_t xread(int fd, void *buf, size_t len)
{
ssize_t nr;
@@ -340,6 +351,11 @@ static inline ssize_t xread(int fd, void *buf, size_t len)
}
}
+/*
+ * xwrite() is the same a write(), but it automatically restarts write()
+ * operations with a recoverable error (EAGAIN and EINTR). xwrite() DOES NOT
+ * GUARANTEE that "len" bytes is written even if the operation is successful.
+ */
static inline ssize_t xwrite(int fd, const void *buf, size_t len)
{
ssize_t nr;
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index 95c5eec51..bdac5d51b 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -772,7 +772,7 @@ sub commit {
waitpid($pid,0);
die "Error running git-commit-tree: $?\n" if $?;
- system("git-update-ref $remote/$branch $cid") == 0
+ system('git-update-ref', "$remote/$branch", $cid) == 0
or die "Cannot write branch $branch for update: $!\n";
if ($tag) {
diff --git a/git-svn.perl b/git-svn.perl
index b864b54a4..e47b1ea6c 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -410,10 +410,12 @@ sub cmd_dcommit {
$head ||= 'HEAD';
my @refs;
my ($url, $rev, $uuid, $gs) = working_head_info($head, \@refs);
- print "Committing to $url ...\n";
+ if ($url) {
+ print "Committing to $url ...\n";
+ }
unless ($gs) {
die "Unable to determine upstream SVN information from ",
- "$head history\n";
+ "$head history.\nPerhaps the repository is empty.";
}
my $last_rev;
my ($linear_refs, $parents) = linearize_history($gs, \@refs);
@@ -612,7 +614,7 @@ sub cmd_create_ignore {
print GITIGNORE "$s\n";
close(GITIGNORE)
or fatal("Failed to close `$ignore': $!");
- command_noisy('add', $ignore);
+ command_noisy('add', '-f', $ignore);
});
}
@@ -2375,8 +2377,7 @@ sub check_author {
my ($author) = @_;
if (!defined $author || length $author == 0) {
$author = '(no author)';
- }
- if (defined $::_authors && ! defined $::users{$author}) {
+ } elsif (defined $::_authors && ! defined $::users{$author}) {
die "Author: $author not defined in $::_authors file\n";
}
$author;
@@ -2427,13 +2428,15 @@ sub make_log_entry {
$name_field = $1;
}
if (!defined $name_field) {
- #
+ if (!defined $email) {
+ $email = $name;
+ }
} elsif ($name_field =~ /(.*?)\s+<(.*)>/) {
($name, $email) = ($1, $2);
} elsif ($name_field =~ /(.*)@/) {
($name, $email) = ($1, $name_field);
} else {
- ($name, $email) = ($name_field, 'unknown');
+ ($name, $email) = ($name_field, $name_field);
}
}
if (defined $headrev && $self->use_svm_props) {
@@ -2519,6 +2522,7 @@ sub rebuild_from_rev_db {
my ($self, $path) = @_;
my $r = -1;
open my $fh, '<', $path or croak "open: $!";
+ binmode $fh or croak "binmode: $!";
while (<$fh>) {
length($_) == 41 or croak "inconsistent size in ($_) != 41";
chomp($_);
@@ -2616,6 +2620,7 @@ sub rebuild {
sub _rev_map_set {
my ($fh, $rev, $commit) = @_;
+ binmode $fh or croak "binmode: $!";
my $size = (stat($fh))[7];
($size % 24) == 0 or croak "inconsistent size: $size";
@@ -2719,6 +2724,7 @@ sub rev_map_max {
my $map_path = $self->map_path;
stat $map_path or return $want_commit ? (0, undef) : 0;
sysopen(my $fh, $map_path, O_RDONLY) or croak "open: $!";
+ binmode $fh or croak "binmode: $!";
my $size = (stat($fh))[7];
($size % 24) == 0 or croak "inconsistent size: $size";
@@ -2751,6 +2757,7 @@ sub rev_map_get {
return undef unless -e $map_path;
sysopen(my $fh, $map_path, O_RDONLY) or croak "open: $!";
+ binmode $fh or croak "binmode: $!";
my $size = (stat($fh))[7];
($size % 24) == 0 or croak "inconsistent size: $size";
diff --git a/git.c b/git.c
index c4e4644b3..89b431fa2 100644
--- a/git.c
+++ b/git.c
@@ -347,7 +347,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "shortlog", cmd_shortlog, USE_PAGER },
{ "show-branch", cmd_show_branch, RUN_SETUP },
{ "show", cmd_show, RUN_SETUP | USE_PAGER },
- { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
+ { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE | USE_PAGER },
{ "stripspace", cmd_stripspace },
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
{ "tag", cmd_tag, RUN_SETUP },
diff --git a/gitweb/INSTALL b/gitweb/INSTALL
index 743f2d444..f7194dbef 100644
--- a/gitweb/INSTALL
+++ b/gitweb/INSTALL
@@ -29,40 +29,40 @@ Build time configuration
See also "How to configure gitweb for your local system" in README
file for gitweb (in gitweb/README).
-- There are many configuration variables which affects building of
+- There are many configuration variables which affect building of
gitweb.cgi; see "default configuration for gitweb" section in main
(top dir) Makefile, and instructions for building gitweb/gitweb.cgi
target.
- One of most important is where to find git wrapper binary. Gitweb
- tries to find git wrapper at $(bindir)/git, so you have to set $bindir
+ One of the most important is where to find the git wrapper binary. Gitweb
+ tries to find the git wrapper at $(bindir)/git, so you have to set $bindir
when building gitweb.cgi, or $prefix from which $bindir is derived. If
- you build and install gitweb together with the rest of git suite,
+ you build and install gitweb together with the rest of the git suite,
there should be no problems. Otherwise, if git was for example
installed from a binary package, you have to set $prefix (or $bindir)
accordingly.
- Another important issue is where are git repositories you want to make
- available to gitweb. By default gitweb search for repositories under
+ available to gitweb. By default gitweb searches for repositories under
/pub/git; if you want to have projects somewhere else, like /home/git,
use GITWEB_PROJECTROOT build configuration variable.
By default all git repositories under projectroot are visible and
- available to gitweb. List of projects is generated by default by
+ available to gitweb. The list of projects is generated by default by
scanning the projectroot directory for git repositories. This can be
changed (configured) as described in "Gitweb repositories" section
below.
- Note that gitweb deals directly with object database, and does not
- need working directory; the name of the project is the name of its
+ Note that gitweb deals directly with the object database, and does not
+ need a working directory; the name of the project is the name of its
repository object database, usually projectname.git for bare
repositories. If you want to provide gitweb access to non-bare (live)
- repository, you can make projectname.git symbolic link under
+ repositories, you can make projectname.git a symbolic link under
projectroot linking to projectname/.git (but it is just
a suggestion).
- You can control where gitweb tries to find its main CSS style file,
- its favicon and logo with GITWEB_CSS, GITWEB_FAVICON and GITWEB_LOGO
+ its favicon and logo with the GITWEB_CSS, GITWEB_FAVICON and GITWEB_LOGO
build configuration variables. By default gitweb tries to find them
in the same directory as gitweb.cgi script.
@@ -91,17 +91,17 @@ Gitweb config file
See also "Runtime gitweb configuration" section in README file
for gitweb (in gitweb/README).
-- You can configure gitweb further using gitweb configuration file;
- by default it is file named gitweb_config.perl in the same place as
- gitweb.cgi script. You can control default place for config file
- using GITWEB_CONFIG build configuration variable, and you can set it
- using GITWEB_CONFIG environmental variable. If this file does not
+- You can configure gitweb further using the gitweb configuration file;
+ by default this is a file named gitweb_config.perl in the same place as
+ gitweb.cgi script. You can control the default place for the config file
+ using the GITWEB_CONFIG build configuration variable, and you can set it
+ using the GITWEB_CONFIG environment variable. If this file does not
exist, gitweb looks for a system-wide configuration file, normally
/etc/gitweb.conf. You can change the default using the
GITWEB_CONFIG_SYSTEM build configuration variable, and override it
- through GITWEB_CONFIG_SYSTEM environmental variable.
+ through the GITWEB_CONFIG_SYSTEM environment variable.
-- Gitweb config file is [fragment] of perl code. You can set variables
+- The gitweb config file is a fragment of perl code. You can set variables
using "our $variable = value"; text from "#" character until the end
of a line is ignored. See perlsyn(1) for details.
@@ -128,36 +128,37 @@ Gitweb repositories
-------------------
- By default all git repositories under projectroot are visible and
- available to gitweb. List of projects is generated by default by
+ available to gitweb. The list of projects is generated by default by
scanning the projectroot directory for git repositories (for object
databases to be more exact).
- You can provide pre-generated list of [visible] repositories,
+ You can provide a pre-generated list of [visible] repositories,
together with information about their owners (the project ownership
- is taken from owner of repository directory otherwise), by setting
- GITWEB_LIST build configuration variable (or $projects_list variable
- in gitweb config file) to point to a plain file.
-
- Each line of projects list file should consist of url-encoded path
- to project repository database (relative to projectroot) separated
- by space from url-encoded project owner; spaces in both project path
- and project owner have to be encoded as either '%20' or '+'.
-
- You can generate projects list index file using project_index action
- (the 'TXT' link on projects list page) directly from gitweb.
-
-- By default even if project is not visible on projects list page, you
- can view it nevertheless by hand-crafting gitweb URL. You can set
- GITWEB_STRICT_EXPORT build configuration variable (or $strict_export
- variable in gitweb config file) to only allow viewing of
+ defaults to the owner of the repository directory otherwise), by setting
+ the GITWEB_LIST build configuration variable (or the $projects_list
+ variable in the gitweb config file) to point to a plain file.
+
+ Each line of the projects list file should consist of the url-encoded path
+ to the project repository database (relative to projectroot), followed
+ by the url-encoded project owner on the same line (separated by a space).
+ Spaces in both project path and project owner have to be encoded as either
+ '%20' or '+'.
+
+ You can generate the projects list index file using the project_index
+ action (the 'TXT' link on projects list page) directly from gitweb.
+
+- By default, even if a project is not visible on projects list page, you
+ can view it nevertheless by hand-crafting a gitweb URL. You can set the
+ GITWEB_STRICT_EXPORT build configuration variable (or the $strict_export
+ variable in the gitweb config file) to only allow viewing of
repositories also shown on the overview page.
- Alternatively, you can configure gitweb to only list and allow
- viewing of the explicitly exported repositories, via
- GITWEB_EXPORT_OK build configuration variable (or $export_ok
+ viewing of the explicitly exported repositories, via the
+ GITWEB_EXPORT_OK build configuration variable (or the $export_ok
variable in gitweb config file). If it evaluates to true, gitweb
- show repository only if this file exists in its object database
- (if directory has the magic file $export_ok).
+ shows repositories only if this file exists in its object database
+ (if directory has the magic file named $export_ok).
Generating projects list using gitweb
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/gitweb/README b/gitweb/README
index 8dfe335f7..8f7ea367b 100644
--- a/gitweb/README
+++ b/gitweb/README
@@ -2,7 +2,7 @@ GIT web Interface
=================
The one working on:
- http://www.kernel.org/git/
+ http://git.kernel.org/
From the git version 1.4.0 gitweb is bundled with git.
@@ -10,13 +10,13 @@ From the git version 1.4.0 gitweb is bundled with git.
How to configure gitweb for your local system
---------------------------------------------
-See also "Build time configuration" section in INSTALL
+See also the "Build time configuration" section in the INSTALL
file for gitweb (in gitweb/INSTALL).
You can specify the following configuration variables when building GIT:
* GIT_BINDIR
- Points out where to find git executable. You should set up it to
- the place where git binary was installed (usually /usr/bin) if you
+ Points where to find the git executable. You should set it up to
+ the place where the git binary was installed (usually /usr/bin) if you
don't install git from sources together with gitweb. [Default: $(bindir)]
* GITWEB_SITENAME
Shown in the title of all generated pages, defaults to the server name
@@ -24,13 +24,13 @@ You can specify the following configuration variables when building GIT:
* GITWEB_PROJECTROOT
The root directory for all projects shown by gitweb. Must be set
correctly for gitweb to find repositories to display. See also
- "Gitweb repositories" in INSTALL file for gitweb. [Default: /pub/git]
+ "Gitweb repositories" in the INSTALL file for gitweb. [Default: /pub/git]
* GITWEB_PROJECT_MAXDEPTH
- The filesystem traversing limit for getting projects list; the number
+ The filesystem traversing limit for getting the project list; the number
is taken as depth relative to the projectroot. It is used when
GITWEB_LIST is a directory (or is not set; then project root is used).
Is is meant to speed up project listing on large work trees by limiting
- find depth. [Default: 2007]
+ search depth. [Default: 2007]
* GITWEB_LIST
Points to a directory to scan for projects (defaults to project root
if not set / if empty) or to a file with explicit listing of projects
@@ -72,15 +72,15 @@ You can specify the following configuration variables when building GIT:
Git base URLs used for URL to where fetch project from, i.e. full
URL is "$git_base_url/$project". Shown on projects summary page.
Repository URL for project can be also configured per repository; this
- takes precendence over URL composed from base URL and project name.
+ takes precedence over URLs composed from base URL and a project name.
Note that you can setup multiple base URLs (for example one for
- git:// protocol access, one for http:// access) from gitweb config
- file. [No default]
+ git:// protocol access, another for http:// access) from the gitweb
+ config file. [No default]
* GITWEB_CSS
Points to the location where you put gitweb.css on your web server
- (or to be more generic URI of gitweb stylesheet). Relative to base
- URI of gitweb. Note that you can setup multiple stylesheets from
- gitweb config file. [Default: gitweb.css]
+ (or to be more generic, the URI of gitweb stylesheet). Relative to the
+ base URI of gitweb. Note that you can setup multiple stylesheets from
+ the gitweb config file. [Default: gitweb.css]
* GITWEB_LOGO
Points to the location where you put git-logo.png on your web server
(or to be more generic URI of logo, 72x27 size, displayed in top right
@@ -121,15 +121,15 @@ Ultimate description on how to reconfigure the default features setting
in your `GITWEB_CONFIG` or per-project in `project.git/config` can be found
as comments inside 'gitweb.cgi'.
-See also "Gitweb config file" (with example of gitweb config file), and
-"Gitweb repositories" sections in INSTALL file for gitweb.
+See also the "Gitweb config file" (with an example of config file), and
+the "Gitweb repositories" sections in INSTALL file for gitweb.
-Gitweb config file is [fragment] of perl code. You can set variables
+The gitweb config file is a fragment of perl code. You can set variables
using "our $variable = value"; text from "#" character until the end
of a line is ignored. See perlsyn(1) man page for details.
-Below there is list of vaiables which you might want to set in gitweb config.
+Below is the list of variables which you might want to set in gitweb config.
See the top of 'gitweb.cgi' for the full list of variables and their
descriptions.
@@ -140,7 +140,7 @@ You can set, among others, the following variables in gitweb config files
(with the exception of $projectroot and $projects_list this list does
not include variables usually directly set during build):
* $GIT
- Cure git executable to use. By default set to "$GIT_BINDIR/git", which
+ Core git executable to use. By default set to "$GIT_BINDIR/git", which
in turn is by default set to "$(bindir)/git". If you use git from binary
package, set this to "/usr/bin/git". This can just be "git" if your
webserver has a sensible PATH. If you have multiple git versions
@@ -176,7 +176,7 @@ not include variables usually directly set during build):
to make it easier to upgrade gitweb. You can add 'site' stylesheet
for example by using
push @stylesheets, "gitweb-site.css";
- in gitweb config file.
+ in the gitweb config file.
* $logo_url, $logo_label
URI and label (title) of GIT logo link (or your site logo, if you choose
to use different logo image). By default they point to git homepage;
@@ -198,12 +198,12 @@ not include variables usually directly set during build):
Default mimetype for blob_plain (raw) view, if mimetype checking
doesn't result in some other type; by default 'text/plain'.
* $default_text_plain_charset
- Default charset for text files. If not set, web serwer configuration
+ Default charset for text files. If not set, web server configuration
would be used.
* $mimetypes_file
File to use for (filename extension based) guessing of MIME types before
- trying /etc/mime.types. Path, if relative, is taken currently as taken
- relative to current git repositoy.
+ trying /etc/mime.types. Path, if relative, is taken currently as
+ relative to the current git repository.
* $fallback_encoding
Gitweb assumes this charset if line contains non-UTF-8 characters.
Fallback decoding is used without error checking, so it can be even
@@ -232,14 +232,14 @@ You can use the following files in repository:
single line description of a project (of a repository). Plain text file;
HTML will be escaped. By default set to
Unnamed repository; edit this file to name it for gitweb.
- from the template during creating repository. You can use
+ from the template during repository creation. You can use the
gitweb.description repo configuration variable, but the file takes
- precendence.
+ precedence.
* cloneurl (or multiple-valued gitweb.url)
File with repository URL (used for clone and fetch), one per line.
Displayed in the project summary page. You can use multiple-valued
gitweb.url repository configuration variable for that, but the file
- takes precendence.
+ takes precedence.
* gitweb.owner
You can use the gitweb.owner repository configuration variable to set
repository's owner. It is displayed in the project list and summary
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index a48bebb1b..f83567ec3 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -511,7 +511,7 @@ sub evaluate_path_info {
}
# do not change any parameters if an action is given using the query string
return if $action;
- $path_info =~ s,^$project/*,,;
+ $path_info =~ s,^\Q$project\E/*,,;
my ($refname, $pathname) = split(/:/, $path_info, 2);
if (defined $pathname) {
# we got "project.git/branch:filename" or "project.git/branch:dir/"
@@ -633,7 +633,7 @@ sub href(%) {
my ($use_pathinfo) = gitweb_check_feature('pathinfo');
if ($use_pathinfo) {
# use PATH_INFO for project name
- $href .= "/$params{'project'}" if defined $params{'project'};
+ $href .= "/".esc_url($params{'project'}) if defined $params{'project'};
delete $params{'project'};
# Summary just uses the project path URL
@@ -2575,7 +2575,7 @@ EOF
my $action = $my_uri;
my ($use_pathinfo) = gitweb_check_feature('pathinfo');
if ($use_pathinfo) {
- $action .= "/$project";
+ $action .= "/".esc_url($project);
} else {
$cgi->param("p", $project);
}
diff --git a/imap-send.c b/imap-send.c
index 04afbc492..db6559725 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1303,8 +1303,11 @@ main(int argc, char **argv)
return 1;
}
if (!server.host) {
- fprintf( stderr, "no imap host specified\n" );
- return 1;
+ if (!server.tunnel) {
+ fprintf( stderr, "no imap host specified\n" );
+ return 1;
+ }
+ server.host = "tunnel";
}
/* read the messages */
diff --git a/log-tree.c b/log-tree.c
index 8f5436b74..d3fb0e520 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -208,14 +208,13 @@ void log_write_email_headers(struct rev_info *opt, const char *name,
*extra_headers_p = extra_headers;
}
-void show_log(struct rev_info *opt, const char *sep)
+void show_log(struct rev_info *opt)
{
struct strbuf msgbuf;
struct log_info *log = opt->loginfo;
struct commit *commit = log->commit, *parent = log->parent;
int abbrev = opt->diffopt.abbrev;
int abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;
- const char *extra;
const char *subject = NULL, *extra_headers = opt->extra_headers;
int need_8bit_cte = 0;
@@ -240,17 +239,10 @@ void show_log(struct rev_info *opt, const char *sep)
}
/*
- * The "oneline" format has several special cases:
- * - The pretty-printed commit lacks a newline at the end
- * of the buffer, but we do want to make sure that we
- * have a newline there. If the separator isn't already
- * a newline, add an extra one.
- * - unlike other log messages, the one-line format does
- * not have an empty line between entries.
+ * If use_terminator is set, add a newline at the end of the entry.
+ * Otherwise, add a diffopt.line_termination character before all
+ * entries but the first. (IOW, as a separator between entries)
*/
- extra = "";
- if (*sep != '\n' && opt->use_terminator)
- extra = "\n";
if (opt->shown_one && !opt->use_terminator)
putchar(opt->diffopt.line_termination);
opt->shown_one = 1;
@@ -292,10 +284,8 @@ void show_log(struct rev_info *opt, const char *sep)
show_reflog_message(opt->reflog_info,
opt->commit_format == CMIT_FMT_ONELINE,
opt->date_mode);
- if (opt->commit_format == CMIT_FMT_ONELINE) {
- printf("%s", sep);
+ if (opt->commit_format == CMIT_FMT_ONELINE)
return;
- }
}
}
@@ -317,10 +307,10 @@ void show_log(struct rev_info *opt, const char *sep)
if (opt->show_log_size)
printf("log size %i\n", (int)msgbuf.len);
- if (msgbuf.len) {
+ if (msgbuf.len)
fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
- printf("%s%s", extra, sep);
- }
+ if (opt->use_terminator)
+ putchar('\n');
strbuf_release(&msgbuf);
}
@@ -342,7 +332,7 @@ int log_tree_diff_flush(struct rev_info *opt)
* an extra newline between the end of log and the
* output for readability.
*/
- show_log(opt, opt->diffopt.msg_sep);
+ show_log(opt);
if ((opt->diffopt.output_format & ~DIFF_FORMAT_NO_OUTPUT) &&
opt->verbose_header &&
opt->commit_format != CMIT_FMT_ONELINE) {
@@ -430,7 +420,7 @@ int log_tree_commit(struct rev_info *opt, struct commit *commit)
shown = log_tree_diff(opt, commit, &log);
if (!shown && opt->loginfo && opt->always_show_header) {
log.parent = NULL;
- show_log(opt, "");
+ show_log(opt);
shown = 1;
}
opt->loginfo = NULL;
diff --git a/log-tree.h b/log-tree.h
index 8946ff377..59ba4c48b 100644
--- a/log-tree.h
+++ b/log-tree.h
@@ -11,7 +11,7 @@ void init_log_tree_opt(struct rev_info *);
int log_tree_diff_flush(struct rev_info *);
int log_tree_commit(struct rev_info *, struct commit *);
int log_tree_opt_parse(struct rev_info *, const char **, int);
-void show_log(struct rev_info *opt, const char *sep);
+void show_log(struct rev_info *opt);
void show_decorations(struct commit *commit);
void log_write_email_headers(struct rev_info *opt, const char *name,
const char **subject_p,
diff --git a/pack-write.c b/pack-write.c
index 665e2b29b..c66c8af72 100644
--- a/pack-write.c
+++ b/pack-write.c
@@ -183,7 +183,6 @@ void fixup_pack_header_footer(int pack_fd,
char *index_pack_lockfile(int ip_out)
{
- int len, s;
char packname[46];
/*
@@ -193,11 +192,8 @@ char *index_pack_lockfile(int ip_out)
* case, we need it to remove the corresponding .keep file
* later on. If we don't get that then tough luck with it.
*/
- for (len = 0;
- len < 46 && (s = xread(ip_out, packname+len, 46-len)) > 0;
- len += s);
- if (len == 46 && packname[45] == '\n' &&
- memcmp(packname, "keep\t", 5) == 0) {
+ if (read_in_full(ip_out, packname, 46) == 46 && packname[45] == '\n' &&
+ memcmp(packname, "keep\t", 5) == 0) {
char path[PATH_MAX];
packname[45] = 0;
snprintf(path, sizeof(path), "%s/pack/pack-%s.keep",
diff --git a/path.c b/path.c
index f4ed97999..b7c24a2aa 100644
--- a/path.c
+++ b/path.c
@@ -91,7 +91,8 @@ int validate_headref(const char *path)
struct stat st;
char *buf, buffer[256];
unsigned char sha1[20];
- int len, fd;
+ int fd;
+ ssize_t len;
if (lstat(path, &st) < 0)
return -1;
@@ -266,24 +267,25 @@ int adjust_shared_perm(const char *path)
if (lstat(path, &st) < 0)
return -1;
mode = st.st_mode;
- if (mode & S_IRUSR)
- mode |= (shared_repository == PERM_GROUP
- ? S_IRGRP
- : (shared_repository == PERM_EVERYBODY
- ? (S_IRGRP|S_IROTH)
- : 0));
-
- if (mode & S_IWUSR)
- mode |= S_IWGRP;
-
- if (mode & S_IXUSR)
- mode |= (shared_repository == PERM_GROUP
- ? S_IXGRP
- : (shared_repository == PERM_EVERYBODY
- ? (S_IXGRP|S_IXOTH)
- : 0));
- if (S_ISDIR(mode))
+
+ if (shared_repository) {
+ int tweak = shared_repository;
+ if (!(mode & S_IWUSR))
+ tweak &= ~0222;
+ mode = (mode & ~0777) | tweak;
+ } else {
+ /* Preserve old PERM_UMASK behaviour */
+ if (mode & S_IWUSR)
+ mode |= S_IWGRP;
+ }
+
+ if (S_ISDIR(mode)) {
mode |= FORCE_DIR_SET_GID;
+
+ /* Copy read bits to execute bits */
+ mode |= (shared_repository & 0444) >> 2;
+ }
+
if ((mode & st.st_mode) != mode && chmod(path, mode) < 0)
return -2;
return 0;
diff --git a/pkt-line.c b/pkt-line.c
index 355546a1a..f5d00863a 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -65,16 +65,11 @@ void packet_write(int fd, const char *fmt, ...)
static void safe_read(int fd, void *buffer, unsigned size)
{
- size_t n = 0;
-
- while (n < size) {
- ssize_t ret = xread(fd, (char *) buffer + n, size - n);
- if (ret < 0)
- die("read error (%s)", strerror(errno));
- if (!ret)
- die("The remote end hung up unexpectedly");
- n += ret;
- }
+ ssize_t ret = read_in_full(fd, buffer, size);
+ if (ret < 0)
+ die("read error (%s)", strerror(errno));
+ else if (ret < size)
+ die("The remote end hung up unexpectedly");
}
int packet_read_line(int fd, char *buffer, unsigned size)
diff --git a/refs.c b/refs.c
index 1b0050eee..4db73ed8f 100644
--- a/refs.c
+++ b/refs.c
@@ -368,7 +368,8 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *re
const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *flag)
{
- int depth = MAXDEPTH, len;
+ int depth = MAXDEPTH;
+ ssize_t len;
char buffer[256];
static char ref_buffer[256];
diff --git a/remote.c b/remote.c
index 65ff4141d..870d224a3 100644
--- a/remote.c
+++ b/remote.c
@@ -817,6 +817,26 @@ static struct ref *make_linked_ref(const char *name, struct ref ***tail)
return ret;
}
+static char *guess_ref(const char *name, struct ref *peer)
+{
+ struct strbuf buf = STRBUF_INIT;
+ unsigned char sha1[20];
+
+ const char *r = resolve_ref(peer->name, sha1, 1, NULL);
+ if (!r)
+ return NULL;
+
+ if (!prefixcmp(r, "refs/heads/"))
+ strbuf_addstr(&buf, "refs/heads/");
+ else if (!prefixcmp(r, "refs/tags/"))
+ strbuf_addstr(&buf, "refs/tags/");
+ else
+ return NULL;
+
+ strbuf_addstr(&buf, name);
+ return strbuf_detach(&buf, NULL);
+}
+
static int match_explicit(struct ref *src, struct ref *dst,
struct ref ***dst_tail,
struct refspec *rs,
@@ -825,6 +845,7 @@ static int match_explicit(struct ref *src, struct ref *dst,
struct ref *matched_src, *matched_dst;
const char *dst_value = rs->dst;
+ char *dst_guess;
if (rs->pattern)
return errs;
@@ -871,10 +892,15 @@ static int match_explicit(struct ref *src, struct ref *dst,
case 0:
if (!memcmp(dst_value, "refs/", 5))
matched_dst = make_linked_ref(dst_value, dst_tail);
+ else if((dst_guess = guess_ref(dst_value, matched_src)))
+ matched_dst = make_linked_ref(dst_guess, dst_tail);
else
- error("dst refspec %s does not match any "
- "existing ref on the remote and does "
- "not start with refs/.", dst_value);
+ error("unable to push to unqualified destination: %s\n"
+ "The destination refspec neither matches an "
+ "existing ref on the remote nor\n"
+ "begins with refs/, and we are unable to "
+ "guess a prefix based on the source ref.",
+ dst_value);
break;
default:
matched_dst = NULL;
diff --git a/setup.c b/setup.c
index 3d2d9580f..1b4fa6a8c 100644
--- a/setup.c
+++ b/setup.c
@@ -428,21 +428,53 @@ const char *setup_git_directory_gently(int *nongit_ok)
int git_config_perm(const char *var, const char *value)
{
- if (value) {
- int i;
- if (!strcmp(value, "umask"))
- return PERM_UMASK;
- if (!strcmp(value, "group"))
- return PERM_GROUP;
- if (!strcmp(value, "all") ||
- !strcmp(value, "world") ||
- !strcmp(value, "everybody"))
- return PERM_EVERYBODY;
- i = atoi(value);
- if (i > 1)
- return i;
+ int i;
+ char *endptr;
+
+ if (value == NULL)
+ return PERM_GROUP;
+
+ if (!strcmp(value, "umask"))
+ return PERM_UMASK;
+ if (!strcmp(value, "group"))
+ return PERM_GROUP;
+ if (!strcmp(value, "all") ||
+ !strcmp(value, "world") ||
+ !strcmp(value, "everybody"))
+ return PERM_EVERYBODY;
+
+ /* Parse octal numbers */
+ i = strtol(value, &endptr, 8);
+
+ /* If not an octal number, maybe true/false? */
+ if (*endptr != 0)
+ return git_config_bool(var, value) ? PERM_GROUP : PERM_UMASK;
+
+ /*
+ * Treat values 0, 1 and 2 as compatibility cases, otherwise it is
+ * a chmod value.
+ */
+ switch (i) {
+ case PERM_UMASK: /* 0 */
+ return PERM_UMASK;
+ case OLD_PERM_GROUP: /* 1 */
+ return PERM_GROUP;
+ case OLD_PERM_EVERYBODY: /* 2 */
+ return PERM_EVERYBODY;
}
- return git_config_bool(var, value);
+
+ /* A filemode value was given: 0xxx */
+
+ if ((i & 0600) != 0600)
+ die("Problem with core.sharedRepository filemode value "
+ "(0%.3o).\nThe owner of files must always have "
+ "read and write permissions.", i);
+
+ /*
+ * Mask filemode value. Others can not get write permission.
+ * x flags for directories are handled separately.
+ */
+ return i & 0666;
}
int check_repository_format_version(const char *var, const char *value)
diff --git a/sha1_file.c b/sha1_file.c
index c2ab7ea11..3516777bc 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2466,16 +2466,10 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, int write
int read_pack_header(int fd, struct pack_header *header)
{
- char *c = (char*)header;
- ssize_t remaining = sizeof(struct pack_header);
- do {
- ssize_t r = xread(fd, c, remaining);
- if (r <= 0)
- /* "eof before pack header was fully read" */
- return PH_ERROR_EOF;
- remaining -= r;
- c += r;
- } while (remaining > 0);
+ if (read_in_full(fd, header, sizeof(*header)) < sizeof(*header))
+ /* "eof before pack header was fully read" */
+ return PH_ERROR_EOF;
+
if (header->hdr_signature != htonl(PACK_SIGNATURE))
/* "protocol error (pack signature mismatch detected)" */
return PH_ERROR_PACK_SIGNATURE;
diff --git a/sha1_name.c b/sha1_name.c
index 491d2e7eb..b0b216757 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -351,8 +351,11 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
}
if (0 <= nth)
at_time = 0;
- else
- at_time = approxidate(str + at + 2);
+ else {
+ char *tmp = xstrndup(str + at + 2, reflog_len);
+ at_time = approxidate(tmp);
+ free(tmp);
+ }
if (read_ref_at(real_ref, at_time, nth, sha1, NULL,
&co_time, &co_tz, &co_cnt)) {
if (at_time)
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh
index 3faf135e3..c56d2fbab 100755
--- a/t/t0003-attributes.sh
+++ b/t/t0003-attributes.sh
@@ -21,6 +21,7 @@ test_expect_success 'setup' '
mkdir -p a/b/d a/c &&
(
echo "f test=f"
+ echo "a/i test=a/i"
) >.gitattributes &&
(
echo "g test=a/g" &&
@@ -46,4 +47,11 @@ test_expect_success 'attribute test' '
'
+test_expect_success 'root subdir attribute test' '
+
+ attr_check a/i a/i &&
+ attr_check subdir/a/i unspecified
+
+'
+
test_done
diff --git a/t/t0004-unwritable.sh b/t/t0004-unwritable.sh
new file mode 100755
index 000000000..9255c63c0
--- /dev/null
+++ b/t/t0004-unwritable.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+test_description='detect unwritable repository and fail correctly'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+ >file &&
+ git add file &&
+ git commit -m initial &&
+ echo >file &&
+ git add file
+
+'
+
+test_expect_success 'write-tree should notice unwritable repository' '
+
+ (
+ chmod a-w .git/objects
+ test_must_fail git write-tree
+ )
+ status=$?
+ chmod 775 .git/objects
+ (exit $status)
+
+'
+
+test_expect_success 'commit should notice unwritable repository' '
+
+ (
+ chmod a-w .git/objects
+ test_must_fail git commit -m second
+ )
+ status=$?
+ chmod 775 .git/objects
+ (exit $status)
+
+'
+
+test_expect_success 'update-index should notice unwritable repository' '
+
+ (
+ echo a >file &&
+ chmod a-w .git/objects
+ test_must_fail git update-index file
+ )
+ status=$?
+ chmod 775 .git/objects
+ (exit $status)
+
+'
+
+test_expect_success 'add should notice unwritable repository' '
+
+ (
+ echo b >file &&
+ chmod a-w .git/objects
+ test_must_fail git add file
+ )
+ status=$?
+ chmod 775 .git/objects
+ (exit $status)
+
+'
+
+test_done
diff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh
index 6bfe19a4e..5e4252a32 100755
--- a/t/t1301-shared-repo.sh
+++ b/t/t1301-shared-repo.sh
@@ -7,6 +7,16 @@ test_description='Test shared repository initialization'
. ./test-lib.sh
+# User must have read permissions to the repo -> failure on --shared=0400
+test_expect_success 'shared = 0400 (faulty permission u-w)' '
+ mkdir sub && (
+ cd sub && git init --shared=0400
+ )
+ ret="$?"
+ rm -rf sub
+ test $ret != "0"
+'
+
test_expect_success 'shared=all' '
mkdir sub &&
cd sub &&
@@ -33,4 +43,44 @@ test_expect_success 'update-server-info honors core.sharedRepository' '
esac
'
+for u in 0660:rw-rw---- \
+ 0640:rw-r----- \
+ 0600:rw------- \
+ 0666:rw-rw-rw- \
+ 0664:rw-rw-r--
+do
+ x=$(expr "$u" : ".*:\([rw-]*\)") &&
+ y=$(echo "$x" | sed -e "s/w/-/g") &&
+ u=$(expr "$u" : "\([0-7]*\)") &&
+ git config core.sharedrepository "$u" &&
+ umask 0277 &&
+
+ test_expect_success "shared = $u ($y) ro" '
+
+ rm -f .git/info/refs &&
+ git update-server-info &&
+ actual="$(ls -l .git/info/refs)" &&
+ actual=${actual%% *} &&
+ test "x$actual" = "x-$y" || {
+ ls -lt .git/info
+ false
+ }
+ '
+
+ umask 077 &&
+ test_expect_success "shared = $u ($x) rw" '
+
+ rm -f .git/info/refs &&
+ git update-server-info &&
+ actual="$(ls -l .git/info/refs)" &&
+ actual=${actual%% *} &&
+ test "x$actual" = "x-$x" || {
+ ls -lt .git/info
+ false
+ }
+
+ '
+
+done
+
test_done
diff --git a/t/t2002-checkout-cache-u.sh b/t/t2002-checkout-cache-u.sh
index 0f441bcef..70361c806 100755
--- a/t/t2002-checkout-cache-u.sh
+++ b/t/t2002-checkout-cache-u.sh
@@ -21,13 +21,13 @@ test_expect_success \
rm -f path0 &&
git read-tree $t &&
git checkout-index -f -a &&
-! git diff-files | diff - /dev/null'
+test_must_fail git diff-files --exit-code'
test_expect_success \
'with -u, git checkout-index picks up stat information from new files.' '
rm -f path0 &&
git read-tree $t &&
git checkout-index -u -f -a &&
-git diff-files | diff - /dev/null'
+git diff-files --exit-code'
test_done
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index af2d07779..48ff2d424 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -77,6 +77,16 @@ test_expect_success 'add another remote' '
)
'
+test_expect_success 'remote forces tracking branches' '
+(
+ cd test &&
+ case `git config remote.second.fetch` in
+ +*) true ;;
+ *) false ;;
+ esac
+)
+'
+
test_expect_success 'remove remote' '
(
cd test &&
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 6d7e73854..0a757d5b9 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -209,19 +209,7 @@ test_expect_success 'push with weak ambiguity (2)' '
'
-test_expect_success 'push with ambiguity (1)' '
-
- mk_test remotes/origin/master remotes/frotz/master &&
- if git push testrepo master:master
- then
- echo "Oops, should have failed"
- false
- else
- check_push_result $the_first_commit remotes/origin/master remotes/frotz/master
- fi
-'
-
-test_expect_success 'push with ambiguity (2)' '
+test_expect_success 'push with ambiguity' '
mk_test heads/frotz tags/frotz &&
if git push testrepo master:frotz
@@ -285,6 +273,37 @@ test_expect_success 'push with colon-less refspec (4)' '
'
+test_expect_success 'push head with non-existant, incomplete dest' '
+
+ mk_test &&
+ git push testrepo master:branch &&
+ check_push_result $the_commit heads/branch
+
+'
+
+test_expect_success 'push tag with non-existant, incomplete dest' '
+
+ mk_test &&
+ git tag -f v1.0 &&
+ git push testrepo v1.0:tag &&
+ check_push_result $the_commit tags/tag
+
+'
+
+test_expect_success 'push sha1 with non-existant, incomplete dest' '
+
+ mk_test &&
+ test_must_fail git push testrepo `git rev-parse master`:foo
+
+'
+
+test_expect_success 'push ref expression with non-existant, incomplete dest' '
+
+ mk_test &&
+ test_must_fail git push testrepo master^:branch
+
+'
+
test_expect_success 'push with HEAD' '
mk_test heads/master &&
@@ -323,6 +342,15 @@ test_expect_success 'push with +HEAD' '
'
+test_expect_success 'push HEAD with non-existant, incomplete dest' '
+
+ mk_test &&
+ git checkout master &&
+ git push testrepo HEAD:branch &&
+ check_push_result $the_commit heads/branch
+
+'
+
test_expect_success 'push with config remote.*.push = HEAD' '
mk_test heads/local &&
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
new file mode 100755
index 000000000..dc9d63dbf
--- /dev/null
+++ b/t/t5601-clone.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+test_description=clone
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+ rm -fr .git &&
+ test_create_repo src &&
+ (
+ cd src
+ >file
+ git add file
+ git commit -m initial
+ )
+
+'
+
+test_expect_success 'clone with excess parameters' '
+
+ test_must_fail git clone -n "file://$(pwd)/src" dst junk
+
+'
+
+test_done
diff --git a/write_or_die.c b/write_or_die.c
index e125e11d3..32f991402 100644
--- a/write_or_die.c
+++ b/write_or_die.c
@@ -40,7 +40,7 @@ void maybe_flush_or_die(FILE *f, const char *desc)
}
}
-int read_in_full(int fd, void *buf, size_t count)
+ssize_t read_in_full(int fd, void *buf, size_t count)
{
char *p = buf;
ssize_t total = 0;
@@ -57,7 +57,7 @@ int read_in_full(int fd, void *buf, size_t count)
return total;
}
-int write_in_full(int fd, const void *buf, size_t count)
+ssize_t write_in_full(int fd, const void *buf, size_t count)
{
const char *p = buf;
ssize_t total = 0;