summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Documentation/config.txt16
-rw-r--r--Documentation/git-clone.txt1
-rw-r--r--Documentation/git-diff-index.txt4
-rw-r--r--Documentation/git-pack-objects.txt5
-rw-r--r--Documentation/git-repo-config.txt31
-rw-r--r--Documentation/git-show-ref.txt156
-rw-r--r--Documentation/git-update-ref.txt10
-rw-r--r--Makefile11
-rw-r--r--builtin-apply.c8
-rw-r--r--builtin-branch.c221
-rw-r--r--builtin-fmt-merge-msg.c7
-rw-r--r--builtin-for-each-ref.c68
-rw-r--r--builtin-init-db.c4
-rw-r--r--builtin-log.c113
-rw-r--r--builtin-name-rev.c8
-rw-r--r--builtin-pack-refs.c107
-rw-r--r--builtin-prune.c4
-rw-r--r--builtin-push.c4
-rw-r--r--builtin-repo-config.c13
-rw-r--r--builtin-rev-parse.c10
-rw-r--r--builtin-show-branch.c78
-rw-r--r--builtin-show-ref.c147
-rw-r--r--builtin-symbolic-ref.c18
-rw-r--r--builtin-update-index.c6
-rw-r--r--builtin-update-ref.c20
-rw-r--r--builtin.h4
-rw-r--r--cache.h7
-rwxr-xr-xcontrib/completion/git-completion.bash10
-rw-r--r--contrib/emacs/git.el44
-rw-r--r--describe.c4
-rw-r--r--diff.h2
-rw-r--r--fetch-pack.c8
-rw-r--r--fetch.c6
-rw-r--r--fsck-objects.c15
-rwxr-xr-xgit-branch.sh140
-rwxr-xr-xgit-checkout.sh5
-rwxr-xr-xgit-commit.sh10
-rwxr-xr-xgit-fetch.sh10
-rwxr-xr-xgit-revert.sh11
-rwxr-xr-xgit-svnimport.perl29
-rwxr-xr-xgit-tag.sh18
-rw-r--r--git.c4
-rwxr-xr-xgitweb/gitweb.perl519
-rw-r--r--http-push.c4
-rw-r--r--log-tree.c26
-rw-r--r--receive-pack.c93
-rw-r--r--refs.c602
-rw-r--r--refs.h21
-rw-r--r--revision.c4
-rw-r--r--send-pack.c4
-rw-r--r--server-info.c4
-rw-r--r--sha1_file.c5
-rw-r--r--sha1_name.c56
-rwxr-xr-xt/t1400-update-ref.sh7
-rwxr-xr-xt/t3200-branch.sh9
-rwxr-xr-xt/t3210-pack-refs.sh99
-rw-r--r--tree-diff.c18
-rw-r--r--upload-pack.c6
-rw-r--r--wt-status.c6
60 files changed, 2092 insertions, 790 deletions
diff --git a/.gitignore b/.gitignore
index b670877510..4c8c8e4115 100644
--- a/.gitignore
+++ b/.gitignore
@@ -75,6 +75,7 @@ git-name-rev
git-mv
git-pack-redundant
git-pack-objects
+git-pack-refs
git-parse-remote
git-patch-id
git-peek-remote
@@ -106,6 +107,7 @@ git-shortlog
git-show
git-show-branch
git-show-index
+git-show-ref
git-ssh-fetch
git-ssh-pull
git-ssh-push
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 026d4cf9ad..d9e73da2a7 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -71,12 +71,16 @@ core.preferSymlinkRefs::
expect HEAD to be a symbolic link.
core.logAllRefUpdates::
- If true, `git-update-ref` will append a line to
- "$GIT_DIR/logs/<ref>" listing the new SHA1 and the date/time
- of the update. If the file does not exist it will be
- created automatically. This information can be used to
- determine what commit was the tip of a branch "2 days ago".
- This value is false by default (no logging).
+ Updates to a ref <ref> is logged to the file
+ "$GIT_DIR/logs/<ref>", by appending the new and old
+ SHA1, the date/time and the reason of the update, but
+ only when the file exists. If this configuration
+ variable is set to true, missing "$GIT_DIR/logs/<ref>"
+ file is automatically created for branch heads.
+
+ This information can be used to determine what commit
+ was the tip of a branch "2 days ago". This value is
+ false by default (no automated creation of log files).
core.repositoryFormatVersion::
Internal variable identifying the repository format and layout
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index f973c64313..86060472ad 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -75,6 +75,7 @@ OPTIONS
this option is used, neither the `origin` branch nor the
default `remotes/origin` file is created.
+--origin <name>::
-o <name>::
Instead of using the branch name 'origin' to keep track
of the upstream repository, use <name> instead. Note
diff --git a/Documentation/git-diff-index.txt b/Documentation/git-diff-index.txt
index 9cd43f105b..2df581c2c9 100644
--- a/Documentation/git-diff-index.txt
+++ b/Documentation/git-diff-index.txt
@@ -54,7 +54,7 @@ If '--cached' is specified, it allows you to ask:
For example, let's say that you have worked on your working directory, updated
some files in the index and are ready to commit. You want to see exactly
-*what* you are going to commit is without having to write a new tree
+*what* you are going to commit, without having to write a new tree
object and compare it that way, and to do that, you just do
git-diff-index --cached HEAD
@@ -68,7 +68,7 @@ matches my working directory. But doing a "git-diff-index" does:
-100644 blob 4161aecc6700a2eb579e842af0b7f22b98443f74 commit.c
+100644 blob 4161aecc6700a2eb579e842af0b7f22b98443f74 git-commit.c
-You can trivially see that the above is a rename.
+You can see easily that the above is a rename.
In fact, "git-diff-index --cached" *should* always be entirely equivalent to
actually doing a "git-write-tree" and comparing that. Except this one is much
diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt
index a1e55054bd..9bd1e39feb 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -47,9 +47,8 @@ base-name::
<base-name> to determine the name of the created file.
When this option is used, the two files are written in
<base-name>-<SHA1>.{pack,idx} files. <SHA1> is a hash
- of object names (currently in random order so it does
- not have any useful meaning) to make the resulting
- filename reasonably unique, and written to the standard
+ of the sorted object names to make the resulting filename
+ based on the pack content, and written to the standard
output of the command.
--stdout::
diff --git a/Documentation/git-repo-config.txt b/Documentation/git-repo-config.txt
index 8a1ab61e94..8199615dde 100644
--- a/Documentation/git-repo-config.txt
+++ b/Documentation/git-repo-config.txt
@@ -3,19 +3,19 @@ git-repo-config(1)
NAME
----
-git-repo-config - Get and set options in .git/config
+git-repo-config - Get and set repository or global options.
SYNOPSIS
--------
[verse]
-'git-repo-config' [type] name [value [value_regex]]
-'git-repo-config' [type] --replace-all name [value [value_regex]]
-'git-repo-config' [type] --get name [value_regex]
-'git-repo-config' [type] --get-all name [value_regex]
-'git-repo-config' [type] --unset name [value_regex]
-'git-repo-config' [type] --unset-all name [value_regex]
-'git-repo-config' -l | --list
+'git-repo-config' [--global] [type] name [value [value_regex]]
+'git-repo-config' [--global] [type] --replace-all name [value [value_regex]]
+'git-repo-config' [--global] [type] --get name [value_regex]
+'git-repo-config' [--global] [type] --get-all name [value_regex]
+'git-repo-config' [--global] [type] --unset name [value_regex]
+'git-repo-config' [--global] [type] --unset-all name [value_regex]
+'git-repo-config' [--global] -l | --list
DESCRIPTION
-----------
@@ -41,8 +41,9 @@ This command will fail if:
. Can not write to .git/config,
. no section was provided,
. the section or key is invalid,
-. you try to unset an option which does not exist, or
-. you try to unset/set an option for which multiple lines match.
+. you try to unset an option which does not exist,
+. you try to unset/set an option for which multiple lines match, or
+. you use --global option without $HOME being properly set.
OPTIONS
@@ -64,14 +65,17 @@ OPTIONS
--get-regexp::
Like --get-all, but interprets the name as a regular expression.
+--global::
+ Use global ~/.gitconfig file rather than the repository .git/config.
+
--unset::
- Remove the line matching the key from .git/config.
+ Remove the line matching the key from config file.
--unset-all::
- Remove all matching lines from .git/config.
+ Remove all matching lines from config file.
-l, --list::
- List all variables set in .git/config.
+ List all variables set in config file.
ENVIRONMENT
@@ -79,6 +83,7 @@ ENVIRONMENT
GIT_CONFIG::
Take the configuration from the given file instead of .git/config.
+ Using the "--global" option forces this to ~/.gitconfig.
GIT_CONFIG_LOCAL::
Currently the same as $GIT_CONFIG; when Git will support global
diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt
new file mode 100644
index 0000000000..5973a82517
--- /dev/null
+++ b/Documentation/git-show-ref.txt
@@ -0,0 +1,156 @@
+git-show-ref(1)
+===============
+
+NAME
+----
+git-show-ref - List references in a local repository
+
+SYNOPSIS
+--------
+[verse]
+'git-show-ref' [-q|--quiet] [--verify] [-h|--head] [-d|--dereference]
+ [-s|--hash] [--abbrev] [--tags] [--heads] [--] <pattern>...
+
+DESCRIPTION
+-----------
+
+Displays references available in a local repository along with the associated
+commit IDs. Results can be filtered using a pattern and tags can be
+dereferenced into object IDs. Additionally, it can be used to test whether a
+particular ref exists.
+
+Use of this utility is encouraged in favor of directly accessing files under
+in the `.git` directory.
+
+OPTIONS
+-------
+
+-h, --head::
+
+ Show the HEAD reference.
+
+--tags, --heads::
+
+ Limit to only "refs/heads" and "refs/tags", respectively. These
+ options are not mutually exclusive; when given both, references stored
+ in "refs/heads" and "refs/tags" are displayed.
+
+-d, --dereference::
+
+ Dereference tags into object IDs as well. They will be shown with "^{}"
+ appended.
+
+-s, --hash::
+
+ Only show the SHA1 hash, not the reference name. When also using
+ --dereference the dereferenced tag will still be shown after the SHA1.
+
+--verify::
+
+ Enable stricter reference checking by requiring an exact ref path.
+ Aside from returning an error code of 1, it will also print an error
+ message if '--quiet' was not specified.
+
+--abbrev, --abbrev=len::
+
+ Abbreviate the object name. When using `--hash`, you do
+ not have to say `--hash --abbrev`; `--hash=len` would do.
+
+-q, --quiet::
+
+ Do not print any results to stdout. When combined with '--verify' this
+ can be used to silently check if a reference exists.
+
+<pattern>::
+
+ Show references matching one or more patterns.
+
+OUTPUT
+------
+
+The output is in the format: '<SHA-1 ID>' '<space>' '<reference name>'.
+
+-----------------------------------------------------------------------------
+$ git show-ref --head --dereference
+832e76a9899f560a90ffd62ae2ce83bbeff58f54 HEAD
+832e76a9899f560a90ffd62ae2ce83bbeff58f54 refs/heads/master
+832e76a9899f560a90ffd62ae2ce83bbeff58f54 refs/heads/origin
+3521017556c5de4159da4615a39fa4d5d2c279b5 refs/tags/v0.99.9c
+6ddc0964034342519a87fe013781abf31c6db6ad refs/tags/v0.99.9c^{}
+055e4ae3ae6eb344cbabf2a5256a49ea66040131 refs/tags/v1.0rc4
+423325a2d24638ddcc82ce47be5e40be550f4507 refs/tags/v1.0rc4^{}
+...
+-----------------------------------------------------------------------------
+
+When using --hash (and not --dereference) the output format is: '<SHA-1 ID>'
+
+-----------------------------------------------------------------------------
+$ git show-ref --heads --hash
+2e3ba0114a1f52b47df29743d6915d056be13278
+185008ae97960c8d551adcd9e23565194651b5d1
+03adf42c988195b50e1a1935ba5fcbc39b2b029b
+...
+-----------------------------------------------------------------------------
+
+EXAMPLE
+-------
+
+To show all references called "master", whether tags or heads or anything
+else, and regardless of how deep in the reference naming hierarchy they are,
+use:
+
+-----------------------------------------------------------------------------
+ git show-ref master
+-----------------------------------------------------------------------------
+
+This will show "refs/heads/master" but also "refs/remote/other-repo/master",
+if such references exists.
+
+When using the '--verify' flag, the command requires an exact path:
+
+-----------------------------------------------------------------------------
+ git show-ref --verify refs/heads/master
+-----------------------------------------------------------------------------
+
+will only match the exact branch called "master".
+
+If nothing matches, gitlink:git-show-ref[1] will return an error code of 1,
+and in the case of verification, it will show an error message.
+
+For scripting, you can ask it to be quiet with the "--quiet" flag, which
+allows you to do things like
+
+-----------------------------------------------------------------------------
+ git-show-ref --quiet --verify -- "refs/heads/$headname" ||
+ echo "$headname is not a valid branch"
+-----------------------------------------------------------------------------
+
+to check whether a particular branch exists or not (notice how we don't
+actually want to show any results, and we want to use the full refname for it
+in order to not trigger the problem with ambiguous partial matches).
+
+To show only tags, or only proper branch heads, use "--tags" and/or "--heads"
+respectively (using both means that it shows tags and heads, but not other
+random references under the refs/ subdirectory).
+
+To do automatic tag object dereferencing, use the "-d" or "--dereference"
+flag, so you can do
+
+-----------------------------------------------------------------------------
+ git show-ref --tags --dereference
+-----------------------------------------------------------------------------
+
+to get a listing of all tags together with what they dereference.
+
+SEE ALSO
+--------
+gitlink:git-ls-remote[1], gitlink:git-peek-remote[1]
+
+AUTHORS
+-------
+Written by Linus Torvalds <torvalds@osdl.org>.
+Man page by Jonas Fonseca <fonseca@diku.dk>.
+
+GIT
+---
+Part of the gitlink:git[7] suite
diff --git a/Documentation/git-update-ref.txt b/Documentation/git-update-ref.txt
index e062030e91..71bcb7954f 100644
--- a/Documentation/git-update-ref.txt
+++ b/Documentation/git-update-ref.txt
@@ -7,7 +7,7 @@ git-update-ref - update the object name stored in a ref safely
SYNOPSIS
--------
-'git-update-ref' [-m <reason>] <ref> <newvalue> [<oldvalue>]
+'git-update-ref' [-m <reason>] (-d <ref> <oldvalue> | <ref> <newvalue> [<oldvalue>])
DESCRIPTION
-----------
@@ -20,7 +20,9 @@ possibly dereferencing the symbolic refs, after verifying that
the current value of the <ref> matches <oldvalue>.
E.g. `git-update-ref refs/heads/master <newvalue> <oldvalue>`
updates the master branch head to <newvalue> only if its current
-value is <oldvalue>.
+value is <oldvalue>. You can specify 40 "0" or an empty string
+as <oldvalue> to make sure that the ref you are creating does
+not exist.
It also allows a "ref" file to be a symbolic pointer to another
ref file by starting with the four-byte header sequence of
@@ -49,6 +51,10 @@ for reading but not for writing (so we'll never write through a
ref symlink to some other tree, if you have copied a whole
archive by creating a symlink tree).
+With `-d` flag, it deletes the named <ref> after verifying it
+still contains <oldvalue>.
+
+
Logging Updates
---------------
If config parameter "core.logAllRefUpdates" is true or the file
diff --git a/Makefile b/Makefile
index 2d62efb5c4..1cc9f586d6 100644
--- a/Makefile
+++ b/Makefile
@@ -158,8 +158,8 @@ BASIC_CFLAGS =
BASIC_LDFLAGS =
SCRIPT_SH = \
- git-bisect.sh git-branch.sh git-checkout.sh \
- git-cherry.sh git-clean.sh git-clone.sh git-commit.sh \
+ git-bisect.sh git-checkout.sh \
+ git-clean.sh git-clone.sh git-commit.sh \
git-fetch.sh \
git-ls-remote.sh \
git-merge-one-file.sh git-parse-remote.sh \
@@ -212,7 +212,7 @@ PROGRAMS = \
EXTRA_PROGRAMS =
BUILT_INS = \
- git-format-patch$X git-show$X git-whatchanged$X \
+ git-format-patch$X git-show$X git-whatchanged$X git-cherry$X \
git-get-tar-commit-id$X \
$(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS))
@@ -270,6 +270,7 @@ BUILTIN_OBJS = \
builtin-annotate.o \
builtin-apply.o \
builtin-archive.o \
+ builtin-branch.o \
builtin-cat-file.o \
builtin-checkout-index.o \
builtin-check-ref-format.o \
@@ -310,7 +311,9 @@ BUILTIN_OBJS = \
builtin-update-ref.o \
builtin-upload-archive.o \
builtin-verify-pack.o \
- builtin-write-tree.o
+ builtin-write-tree.o \
+ builtin-show-ref.o \
+ builtin-pack-refs.o
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
EXTLIBS = -lz
diff --git a/builtin-apply.c b/builtin-apply.c
index 11397f5504..db7cdce1d3 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -1043,10 +1043,14 @@ static int parse_single_patch(char *line, unsigned long size, struct patch *patc
* then not having oldlines means the patch is creation,
* and not having newlines means the patch is deletion.
*/
- if (patch->is_new < 0 && !oldlines)
+ if (patch->is_new < 0 && !oldlines) {
patch->is_new = 1;
- if (patch->is_delete < 0 && !newlines)
+ patch->old_name = NULL;
+ }
+ if (patch->is_delete < 0 && !newlines) {
patch->is_delete = 1;
+ patch->new_name = NULL;
+ }
}
if (0 < patch->is_new && oldlines)
diff --git a/builtin-branch.c b/builtin-branch.c
new file mode 100644
index 0000000000..368b68ec91
--- /dev/null
+++ b/builtin-branch.c
@@ -0,0 +1,221 @@
+/*
+ * Builtin "git branch"
+ *
+ * Copyright (c) 2006 Kristian Høgsberg <krh@redhat.com>
+ * Based on git-branch.sh by Junio C Hamano.
+ */
+
+#include "cache.h"
+#include "refs.h"
+#include "commit.h"
+#include "builtin.h"
+
+static const char builtin_branch_usage[] =
+"git-branch (-d | -D) <branchname> | [-l] [-f] <branchname> [<start-point>] | [-r]";
+
+
+static const char *head;
+static unsigned char head_sha1[20];
+
+static int in_merge_bases(const unsigned char *sha1,
+ struct commit *rev1,
+ struct commit *rev2)
+{
+ struct commit_list *bases, *b;
+ int ret = 0;
+
+ bases = get_merge_bases(rev1, rev2, 1);
+ for (b = bases; b; b = b->next) {
+ if (!hashcmp(sha1, b->item->object.sha1)) {
+ ret = 1;
+ break;
+ }
+ }
+
+ free_commit_list(bases);
+ return ret;
+}
+
+static void delete_branches(int argc, const char **argv, int force)
+{
+ struct commit *rev, *head_rev;
+ unsigned char sha1[20];
+ char *name;
+ int i;
+
+ head_rev = lookup_commit_reference(head_sha1);
+ for (i = 0; i < argc; i++) {
+ if (!strcmp(head, argv[i]))
+ die("Cannot delete the branch you are currently on.");
+
+ name = xstrdup(mkpath("refs/heads/%s", argv[i]));
+ if (!resolve_ref(name, sha1, 1, NULL))
+ die("Branch '%s' not found.", argv[i]);
+
+ rev = lookup_commit_reference(sha1);
+ if (!rev || !head_rev)
+ die("Couldn't look up commit objects.");
+
+ /* This checks whether the merge bases of branch and
+ * HEAD contains branch -- which means that the HEAD
+ * contains everything in both.
+ */
+
+ if (!force &&
+ !in_merge_bases(sha1, rev, head_rev)) {
+ fprintf(stderr,
+ "The branch '%s' is not a strict subset of your current HEAD.\n"
+ "If you are sure you want to delete it, run 'git branch -D %s'.\n",
+ argv[i], argv[i]);
+ exit(1);
+ }
+
+ if (delete_ref(name, sha1))
+ printf("Error deleting branch '%s'\n", argv[i]);
+ else
+ printf("Deleted branch %s.\n", argv[i]);
+
+ free(name);
+ }
+}
+
+static int ref_index, ref_alloc;
+static char **ref_list;
+
+static int append_ref(const char *refname, const unsigned char *sha1, int flags,
+ void *cb_data)
+{
+ if (ref_index >= ref_alloc) {
+ ref_alloc = alloc_nr(ref_alloc);
+ ref_list = xrealloc(ref_list, ref_alloc * sizeof(char *));
+ }
+
+ ref_list[ref_index++] = xstrdup(refname);
+
+ return 0;
+}
+
+static int ref_cmp(const void *r1, const void *r2)
+{
+ return strcmp(*(char **)r1, *(char **)r2);
+}
+
+static void print_ref_list(int remote_only)
+{
+ int i;
+ char c;
+
+ if (remote_only)
+ for_each_remote_ref(append_ref, NULL);
+ else
+ for_each_branch_ref(append_ref, NULL);
+
+ qsort(ref_list, ref_index, sizeof(char *), ref_cmp);
+
+ for (i = 0; i < ref_index; i++) {
+ c = ' ';
+ if (!strcmp(ref_list[i], head))
+ c = '*';
+
+ printf("%c %s\n", c, ref_list[i]);
+ }
+}
+
+static void create_branch(const char *name, const char *start,
+ int force, int reflog)
+{
+ struct ref_lock *lock;
+ struct commit *commit;
+ unsigned char sha1[20];
+ char ref[PATH_MAX], msg[PATH_MAX + 20];
+
+ snprintf(ref, sizeof ref, "refs/heads/%s", name);
+ if (check_ref_format(ref))
+ die("'%s' is not a valid branch name.", name);
+
+ if (resolve_ref(ref, sha1, 1, NULL)) {
+ if (!force)
+ die("A branch named '%s' already exists.", name);
+ else if (!strcmp(head, name))
+ die("Cannot force update the current branch.");
+ }
+
+ if (get_sha1(start, sha1) ||
+ (commit = lookup_commit_reference(sha1)) == NULL)
+ die("Not a valid branch point: '%s'.", start);
+ hashcpy(sha1, commit->object.sha1);
+
+ lock = lock_any_ref_for_update(ref, NULL);
+ if (!lock)
+ die("Failed to lock ref for update: %