aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-count-objects.txt12
-rw-r--r--Documentation/git-diff-tree.txt2
-rw-r--r--Documentation/git-update-index.txt10
-rw-r--r--Documentation/glossary.txt409
-rw-r--r--Documentation/sort_glossary.pl2
-rw-r--r--Makefile9
-rw-r--r--blame.c10
-rw-r--r--builtin-count.c125
-rw-r--r--builtin-push.c312
-rw-r--r--builtin.h3
-rw-r--r--diff.c6
-rwxr-xr-xgit-count-objects.sh31
-rwxr-xr-xgit-cvsserver.perl5
-rw-r--r--git.c2
-rw-r--r--log-tree.c18
-rw-r--r--merge-tree.c6
-rw-r--r--revision.c2
-rw-r--r--sha1_file.c5
-rw-r--r--update-index.c2
19 files changed, 741 insertions, 230 deletions
diff --git a/Documentation/git-count-objects.txt b/Documentation/git-count-objects.txt
index 47216f488..198ce77a8 100644
--- a/Documentation/git-count-objects.txt
+++ b/Documentation/git-count-objects.txt
@@ -7,13 +7,23 @@ git-count-objects - Reports on unpacked objects
SYNOPSIS
--------
-'git-count-objects'
+'git-count-objects' [-v]
DESCRIPTION
-----------
This counts the number of unpacked object files and disk space consumed by
them, to help you decide when it is a good time to repack.
+
+OPTIONS
+-------
+-v::
+ In addition to the number of loose objects and disk
+ space consumed, it reports the number of in-pack
+ objects, and number of objects that can be removed by
+ running `git-prune-packed`.
+
+
Author
------
Written by Junio C Hamano <junkio@cox.net>
diff --git a/Documentation/git-diff-tree.txt b/Documentation/git-diff-tree.txt
index 216916985..906830d4b 100644
--- a/Documentation/git-diff-tree.txt
+++ b/Documentation/git-diff-tree.txt
@@ -92,7 +92,7 @@ separated with a single space are given.
Furthermore, it lists only files which were modified
from all parents.
--cc::
+--cc::
This flag changes the way a merge commit patch is displayed,
in a similar way to the '-c' option. It implies the '-c'
and '-p' options and further compresses the patch output
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index d4137fc87..23f2b6f1a 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -10,12 +10,12 @@ SYNOPSIS
--------
[verse]
'git-update-index'
- [--add] [--remove | --force-remove] [--replace]
- [--refresh [-q] [--unmerged] [--ignore-missing]]
+ [--add] [--remove | --force-remove] [--replace]
+ [--refresh] [-q] [--unmerged] [--ignore-missing]
[--cacheinfo <mode> <object> <file>]\*
[--chmod=(+|-)x]
[--assume-unchanged | --no-assume-unchanged]
- [--really-refresh]
+ [--really-refresh] [--unresolve]
[--info-only] [--index-info]
[-z] [--stdin]
[--verbose]
@@ -80,6 +80,10 @@ OPTIONS
filesystem that has very slow lstat(2) system call
(e.g. cifs).
+--unresolve::
+ Restores the 'unmerged' or 'needs updating' state of a
+ file during a merge if it was cleared by accident.
+
--info-only::
Do not create objects in the object database for all
<file> arguments that follow this flag; just insert
diff --git a/Documentation/glossary.txt b/Documentation/glossary.txt
index 02a9d9c18..39c90ad7a 100644
--- a/Documentation/glossary.txt
+++ b/Documentation/glossary.txt
@@ -1,79 +1,57 @@
-object::
- The unit of storage in git. It is uniquely identified by
- the SHA1 of its contents. Consequently, an object can not
- be changed.
-
-object name::
- The unique identifier of an object. The hash of the object's contents
- using the Secure Hash Algorithm 1 and usually represented by the 40
- character hexadecimal encoding of the hash of the object (possibly
- followed by a white space).
-
-SHA1::
- Synonym for object name.
-
-object identifier::
- Synonym for object name.
-
-hash::
- In git's context, synonym to object name.
+alternate object database::
+ Via the alternates mechanism, a repository can inherit part of its
+ object database from another object database, which is called
+ "alternate".
-object database::
- Stores a set of "objects", and an individual object is identified
- by its object name. The objects usually live in `$GIT_DIR/objects/`.
+bare repository::
+ A bare repository is normally an appropriately named
+ directory with a `.git` suffix that does not have a
+ locally checked-out copy of any of the files under revision
+ control. That is, all of the `git` administrative and
+ control files that would normally be present in the
+ hidden `.git` sub-directory are directly present in
+ the `repository.git` directory instead, and no other files
+ are present and checked out. Usually publishers of public
+ repositories make bare repositories available.
blob object::
Untyped object, e.g. the contents of a file.
-tree object::
- An object containing a list of file names and modes along with refs
- to the associated blob and/or tree objects. A tree is equivalent
- to a directory.
-
-tree::
- Either a working tree, or a tree object together with the
- dependent blob and tree objects (i.e. a stored representation
- of a working tree).
-
-DAG::
- Directed acyclic graph. The commit objects form a directed acyclic
- graph, because they have parents (directed), and the graph of commit
- objects is acyclic (there is no chain which begins and ends with the
- same object).
-
-index::
- A collection of files with stat information, whose contents are
- stored as objects. The index is a stored version of your working
- tree. Truth be told, it can also contain a second, and even a third
- version of a working tree, which are used when merging.
-
-index entry::
- The information regarding a particular file, stored in the index.
- An index entry can be unmerged, if a merge was started, but not
- yet finished (i.e. if the index contains multiple versions of
- that file).
-
-unmerged index:
- An index which contains unmerged index entries.
+branch::
+ A non-cyclical graph of revisions, i.e. the complete history of
+ a particular revision, which is called the branch head. The
+ branch heads are stored in `$GIT_DIR/refs/heads/`.
cache::
Obsolete for: index.
-working tree::
- The set of files and directories currently being worked on,
- i.e. you can work in your working tree without using git at all.
-
-directory::
- The list you get with "ls" :-)
+chain::
+ A list of objects, where each object in the list contains a
+ reference to its successor (for example, the successor of a commit
+ could be one of its parents).
-revision::
- A particular state of files and directories which was stored in
- the object database. It is referenced by a commit object.
+changeset::
+ BitKeeper/cvsps speak for "commit". Since git does not store
+ changes, but states, it really does not make sense to use
+ the term "changesets" with git.
checkout::
The action of updating the working tree to a revision which was
stored in the object database.
+cherry-picking::
+ In SCM jargon, "cherry pick" means to choose a subset of
+ changes out of a series of changes (typically commits)
+ and record them as a new series of changes on top of
+ different codebase. In GIT, this is performed by
+ "git cherry-pick" command to extract the change
+ introduced by an existing commit and to record it based
+ on the tip of the current branch as a new commit.
+
+clean::
+ A working tree is clean, if it corresponds to the revision
+ referenced by the current head. Also see "dirty".
+
commit::
As a verb: The action of storing the current state of the index in the
object database. The result is a revision.
@@ -85,73 +63,90 @@ commit object::
tree object which corresponds to the top directory of the
stored revision.
-parent::
- A commit object contains a (possibly empty) list of the logical
- predecessor(s) in the line of development, i.e. its parents.
+core git::
+ Fundamental data structures and utilities of git. Exposes only
+ limited source code management tools.
-changeset::
- BitKeeper/cvsps speak for "commit". Since git does not store
- changes, but states, it really does not make sense to use
- the term "changesets" with git.
+DAG::
+ Directed acyclic graph. The commit objects form a directed acyclic
+ graph, because they have parents (directed), and the graph of commit
+ objects is acyclic (there is no chain which begins and ends with the
+ same object).
-clean::
- A working tree is clean, if it corresponds to the revision
- referenced by the current head.
+dircache::
+ You are *waaaaay* behind.
dirty::
A working tree is said to be dirty if it contains modifications
which have not been committed to the current branch.
-head::
- The top of a branch. It contains a ref to the corresponding
- commit object.
+directory::
+ The list you get with "ls" :-)
-branch::
- A non-cyclical graph of revisions, i.e. the complete history of
- a particular revision, which is called the branch head. The
- branch heads are stored in `$GIT_DIR/refs/heads/`.
+ent::
+ Favorite synonym to "tree-ish" by some total geeks. See
+ `http://en.wikipedia.org/wiki/Ent_(Middle-earth)` for an in-depth
+ explanation.
-master::
- The default branch. Whenever you create a git repository, a branch
- named "master" is created, and becomes the active branch. In most
- cases, this contains the local development.
+fast forward::
+ A fast-forward is a special type of merge where you have
+ a revision and you are "merging" another branch's changes
+ that happen to be a descendant of what you have.
+ In such these cases, you do not make a new merge commit but
+ instead just update to his revision. This will happen
+ frequently on a tracking branch of a remote repository.
-origin::
- The default upstream branch. Most projects have one upstream
- project which they track, and by default 'origin' is used for
- that purpose. New updates from upstream will be fetched into
- this branch; you should never commit to it yourself.
+fetch::
+ Fetching a branch means to get the branch's head ref from a
+ remote repository, to find out which objects are missing from
+ the local object database, and to get them, too.
-ref::
- A 40-byte hex representation of a SHA1 pointing to a particular
- object. These may be stored in `$GIT_DIR/refs/`.
+file system::
+ Linus Torvalds originally designed git to be a user space file
+ system, i.e. the infrastructure to hold files and directories.
+ That ensured the efficiency and speed of git.
+
+git archive::
+ Synonym for repository (for arch people).
+
+hash::
+ In git's context, synonym to object name.
+
+head::
+ The top of a branch. It contains a ref to the corresponding
+ commit object.
head ref::
A ref pointing to a head. Often, this is abbreviated to "head".
Head refs are stored in `$GIT_DIR/refs/heads/`.
-tree-ish::
- A ref pointing to either a commit object, a tree object, or a
- tag object pointing to a tag or commit or tree object.
+hook::
+ During the normal execution of several git commands,
+ call-outs are made to optional scripts that allow
+ a developer to add functionality or checking.
+ Typically, the hooks allow for a command to be pre-verified
+ and potentially aborted, and allow for a post-notification
+ after the operation is done.
+ The hook scripts are found in the `$GIT_DIR/hooks/` directory,
+ and are enabled by simply making them executable.
-ent::
- Favorite synonym to "tree-ish" by some total geeks. See
- `http://en.wikipedia.org/wiki/Ent_(Middle-earth)` for an in-depth
- explanation.
+index::
+ A collection of files with stat information, whose contents are
+ stored as objects. The index is a stored version of your working
+ tree. Truth be told, it can also contain a second, and even a third
+ version of a working tree, which are used when merging.
-tag object::
- An object containing a ref pointing to another object, which can
- contain a message just like a commit object. It can also
- contain a (PGP) signature, in which case it is called a "signed
- tag object".
+index entry::
+ The information regarding a particular file, stored in the index.
+ An index entry can be unmerged, if a merge was started, but not
+ yet finished (i.e. if the index contains multiple versions of
+ that file).
-tag::
- A ref pointing to a tag or commit object. In contrast to a head,
- a tag is not changed by a commit. Tags (not tag objects) are
- stored in `$GIT_DIR/refs/tags/`. A git tag has nothing to do with
- a Lisp tag (which is called object type in git's context).
- A tag is most typically used to mark a particular point in the
- commit ancestry chain.
+master::
+ The default development branch. Whenever you create a git
+ repository, a branch named "master" is created, and becomes
+ the active branch. In most cases, this contains the local
+ development, though that is purely conventional and not required.
merge::
To merge branches means to try to accumulate the changes since a
@@ -159,55 +154,65 @@ merge::
merge uses heuristics to accomplish that. Evidently, an automatic
merge can fail.
-octopus::
- To merge more than two branches. Also denotes an intelligent
- predator.
+object::
+ The unit of storage in git. It is uniquely identified by
+ the SHA1 of its contents. Consequently, an object can not
+ be changed.
-resolve::
- The action of fixing up manually what a failed automatic merge
- left behind.
+object database::
+ Stores a set of "objects", and an individual object is identified
+ by its object name. The objects usually live in `$GIT_DIR/objects/`.
-rewind::
- To throw away part of the development, i.e. to assign the head to
- an earlier revision.
+object identifier::
+ Synonym for object name.
-rebase::
- To clean a branch by starting from the head of the main line of
- development ("master"), and reapply the (possibly cherry-picked)
- changes from that branch.
+object name::
+ The unique identifier of an object. The hash of the object's contents
+ using the Secure Hash Algorithm 1 and usually represented by the 40
+ character hexadecimal encoding of the hash of the object (possibly
+ followed by a white space).
-repository::
- A collection of refs together with an object database containing
- all objects, which are reachable from the refs, possibly accompanied
- by meta data from one or more porcelains. A repository can
- share an object database with other repositories.
+object type:
+ One of the identifiers "commit","tree","tag" and "blob" describing
+ the type of an object.
-git archive::
- Synonym for repository (for arch people).
+octopus::
+ To merge more than two branches. Also denotes an intelligent
+ predator.
-file system::
- Linus Torvalds originally designed git to be a user space file
- system, i.e. the infrastructure to hold files and directories.
- That ensured the efficiency and speed of git.
+origin::
+ The default upstream tracking branch. Most projects have at
+ least one upstream project which they track. By default
+ 'origin' is used for that purpose. New upstream updates
+ will be fetched into this branch; you should never commit
+ to it yourself.
-alternate object database::
- Via the alternates mechanism, a repository can inherit part of its
- object database from another object database, which is called
- "alternate".
+pack::
+ A set of objects which have been compressed into one file (to save
+ space or to transmit them efficiently).
-reachable::
- An object is reachable from a ref/commit/tree/tag, if there is a
- chain leading from the latter to the former.
+pack index::
+ The list of identifiers, and other information, of the objects in a
+ pack, to assist in efficiently accessing the contents of a pack.
-chain::
- A list of objects, where each object in the list contains a
- reference to its successor (for example, the successor of a commit
- could be one of its parents).
+parent::
+ A commit object contains a (possibly empty) list of the logical
+ predecessor(s) in the line of development, i.e. its parents.
-fetch::
- Fetching a branch means to get the branch's head ref from a
- remote repository, to find out which objects are missing from
- the local object database, and to get them, too.
+pickaxe::
+ The term pickaxe refers to an option to the diffcore routines
+ that help select changes that add or delete a given text string.
+ With the --pickaxe-all option, it can be used to view the
+ full changeset that introduced or removed, say, a particular
+ line of text. See gitlink:git-diff[1].
+
+plumbing::
+ Cute name for core git.
+
+porcelain::
+ Cute name for programs and program suites depending on core git,
+ presenting a high level access to core git. Porcelains expose
+ more of a SCM interface than the plumbing.
pull::
Pulling a branch means to fetch it and merge it.
@@ -221,33 +226,101 @@ push::
the remote head ref. If the remote head is not an ancestor to the
local head, the push fails.
-pack::
- A set of objects which have been compressed into one file (to save
- space or to transmit them efficiently).
+reachable::
+ An object is reachable from a ref/commit/tree/tag, if there is a
+ chain leading from the latter to the former.
-pack index::
- The list of identifiers, and other information, of the objects in a
- pack, to assist in efficiently accessing the contents of a pack.
+rebase::
+ To clean a branch by starting from the head of the main line of
+ development ("master"), and reapply the (possibly cherry-picked)
+ changes from that branch.
-core git::
- Fundamental data structures and utilities of git. Exposes only
- limited source code management tools.
+ref::
+ A 40-byte hex representation of a SHA1 or a name that denotes
+ a particular object. These may be stored in `$GIT_DIR/refs/`.
+
+refspec::
+ A refspec is used by fetch and push to describe the mapping
+ between remote ref and local ref. They are combined with
+ a colon in the format <src>:<dst>, preceded by an optional
+ plus sign, +. For example:
+ `git fetch $URL refs/heads/master:refs/heads/origin`
+ means "grab the master branch head from the $URL and store
+ it as my origin branch head".
+ And `git push $URL refs/heads/master:refs/heads/to-upstream`
+ means "publish my master branch head as to-upstream master head
+ at $URL". See also gitlink:git-push[1]
-plumbing::
- Cute name for core git.
+repository::
+ A collection of refs together with an object database containing
+ all objects, which are reachable from the refs, possibly accompanied
+ by meta data from one or more porcelains. A repository can
+ share an object database with other repositories.
-porcelain::
- Cute name for programs and program suites depending on core git,
- presenting a high level access to core git. Porcelains expose
- more of a SCM interface than the plumbing.
+resolve::
+ The action of fixing up manually what a failed automatic merge
+ left behind.
-object type:
- One of the identifiers "commit","tree","tag" and "blob" describing
- the type of an object.
+revision::
+ A particular state of files and directories which was stored in
+ the object database. It is referenced by a commit object.
+
+rewind::
+ To throw away part of the development, i.e. to assign the head to
+ an earlier revision.
SCM::
Source code management (tool).
-dircache::
- You are *waaaaay* behind.
+SHA1::
+ Synonym for object name.
+
+topic branch::
+ A regular git branch that is used by a developer to
+ identify a conceptual line of development. Since branches
+ are very easy and inexpensive, it is often desirable to
+ have several small branches that each contain very well
+ defined concepts or small incremental yet related changes.
+
+tracking branch::
+ A regular git branch that is used to follow changes from
+ another repository. A tracking branch should not contain
+ direct modifications or have local commits made to it.
+ A tracking branch can usually be identified as the
+ right-hand-side ref in a Pull: refspec.
+
+tree object::
+ An object containing a list of file names and modes along with refs
+ to the associated blob and/or tree objects. A tree is equivalent
+ to a directory.
+
+tree::
+ Either a working tree, or a tree object together with the
+ dependent blob and tree objects (i.e. a stored representation
+ of a working tree).
+
+tree-ish::
+ A ref pointing to either a commit object, a tree object, or a
+ tag object pointing to a tag or commit or tree object.
+
+tag object::
+ An object containing a ref pointing to another object, which can
+ contain a message just like a commit object. It can also
+ contain a (PGP) signature, in which case it is called a "signed
+ tag object".
+
+tag::
+ A ref pointing to a tag or commit object. In contrast to a head,
+ a tag is not changed by a commit. Tags (not tag objects) are
+ stored in `$GIT_DIR/refs/tags/`. A git tag has nothing to do with
+ a Lisp tag (which is called object type in git's context).
+ A tag is most typically used to mark a particular point in the
+ commit ancestry chain.
+
+unmerged index:
+ An index which contains unmerged index entries.
+
+working tree::
+ The set of files and directories currently being worked on,
+ i.e. you can work in your working tree without using git at all.
diff --git a/Documentation/sort_glossary.pl b/Documentation/sort_glossary.pl
index e57dc78e0..e0bc552a6 100644
--- a/Documentation/sort_glossary.pl
+++ b/Documentation/sort_glossary.pl
@@ -48,7 +48,7 @@ This list is sorted alphabetically:
';
@keys=sort {uc($a) cmp uc($b)} keys %terms;
-$pattern='(\b'.join('\b|\b',reverse @keys).'\b)';
+$pattern='(\b(?<!link:git-)'.join('\b|\b(?<!link:git-)',reverse @keys).'\b)';
foreach $key (@keys) {
$terms{$key}=~s/$pattern/sprintf "<<ref_".no_spaces($1).",$1>>";/eg;
print '[[ref_'.no_spaces($key).']]'.$key."::\n"
diff --git a/Makefile b/Makefile
index 8ce27a65f..67559c9f4 100644
--- a/Makefile
+++ b/Makefile
@@ -115,10 +115,10 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
SCRIPT_SH = \
git-add.sh git-bisect.sh git-branch.sh git-checkout.sh \
git-cherry.sh git-clean.sh git-clone.sh git-commit.sh \
- git-count-objects.sh git-diff.sh git-fetch.sh \
+ git-diff.sh git-fetch.sh \
git-format-patch.sh git-ls-remote.sh \
git-merge-one-file.sh git-parse-remote.sh \
- git-prune.sh git-pull.sh git-push.sh git-rebase.sh \
+ git-prune.sh git-pull.sh git-rebase.sh \
git-repack.sh git-request-pull.sh git-reset.sh \
git-resolve.sh git-revert.sh git-rm.sh git-sh-setup.sh \
git-tag.sh git-verify-tag.sh git-whatchanged.sh \
@@ -167,7 +167,8 @@ PROGRAMS = \
git-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X \
git-describe$X git-merge-tree$X git-blame$X git-imap-send$X
-BUILT_INS = git-log$X
+BUILT_INS = git-log$X \
+ git-count-objects$X git-push$X
# what 'all' will build and 'install' will install, in gitexecdir
ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@@ -214,7 +215,7 @@ LIB_OBJS = \
$(DIFF_OBJS)
BUILTIN_OBJS = \
- builtin-log.o builtin-help.o
+ builtin-log.o builtin-help.o builtin-count.o builtin-push.o
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
LIBS = $(GITLIBS) -lz
diff --git a/blame.c b/blame.c
index 07d2d2725..99ceea81d 100644
--- a/blame.c
+++ b/blame.c
@@ -515,9 +515,9 @@ static int compare_tree_path(struct rev_info* revs,
paths[1] = NULL;
diff_tree_setup_paths(get_pathspec(revs->prefix, paths),
- &revs->diffopt);
+ &revs->pruning);
ret = rev_compare_tree(revs, c1->tree, c2->tree);
- diff_tree_release_paths(&revs->diffopt);
+ diff_tree_release_paths(&revs->pruning);
return ret;
}
@@ -531,9 +531,9 @@ static int same_tree_as_empty_path(struct rev_info *revs, struct tree* t1,
paths[1] = NULL;
diff_tree_setup_paths(get_pathspec(revs->prefix, paths),
- &revs->diffopt);
+ &revs->pruning);
ret = rev_same_tree_as_empty(revs, t1);
- diff_tree_release_paths(&revs->diffopt);
+ diff_tree_release_paths(&revs->pruning);
return ret;
}
@@ -834,7 +834,7 @@ int main(int argc, const char **argv)
args[0] = filename;
args[1] = NULL;
- diff_tree_setup_paths(args, &rev.diffopt);
+ diff_tree_setup_paths(args, &rev.pruning);
prepare_revision_walk(&rev);
process_commits(&rev, filename, &initial);
diff --git a/builtin-count.c b/builtin-count.c
new file mode 100644
index 000000000..5ee72df24
--- /dev/null
+++ b/builtin-count.c
@@ -0,0 +1,125 @@
+/*
+ * Builtin "git count-objects".
+ *
+ * Copyright (c) 2006 Junio C Hamano
+ */
+
+#include "cache.h"
+#include "builtin.h"
+
+static const char count_objects_usage[] = "git-count-objects [-v]";
+
+static void count_objects(DIR *d, char *path, int len, int verbose,
+ unsigned long *loose,
+ unsigned long *loose_size,
+ unsigned long *packed_loose,
+ unsigned long *garbage)
+{
+ struct dirent *ent;
+ while ((ent = readdir(d)) != NULL) {
+ char hex[41];
+ unsigned char sha1[20];
+ const char *cp;
+ int bad = 0;
+
+ if ((ent->d_name[0] == '.') &&
+ (ent->d_name[1] == 0 ||
+ ((ent->d_name[1] == '.') && (ent->d_name[2] == 0))))
+ continue;
+ for (cp = ent->d_name; *cp; cp++) {
+ int ch = *cp;
+ if (('0' <= ch && ch <= '9') ||
+ ('a' <= ch && ch <= 'f'))
+ continue;
+ bad = 1;
+ break;
+ }
+ if (cp - ent->d_name != 38)
+ bad = 1;
+ else {
+ struct stat st;
+ memcpy(path + len + 3, ent->d_name, 38);
+ path[len + 2] = '/';
+ path[len + 41] = 0;
+ if (lstat(path, &st) || !S_ISREG(st.st_mode))
+ bad = 1;
+ else
+ (*loose_size) += st.st_blocks;
+ }
+ if (bad) {
+ if (verbose) {
+ error("garbage found: %.*s/%s",
+ len + 2, path, ent->d_name);
+ (*garbage)++;
+ }
+ continue;
+ }
+ (*loose)++;
+ if (!verbose)
+ continue;
+ memcpy(hex, path+len, 2);
+ memcpy(hex+2, ent->d_name, 38);
+ hex[40] = 0;
+ if (get_sha1_hex(hex, sha1))
+ die("internal error");
+ if (has_sha1_pack(sha1))
+ (*packed_loose)++;
+ }
+}
+
+int cmd_count_objects(int ac, const char **av, char **ep)
+{
+ int i;
+ int verbose = 0;
+ const char *objdir = get_object_directory();
+ int len = strlen(objdir);
+ char *path = xmalloc(len + 50);
+ unsigned long loose = 0, packed = 0, packed_loose = 0, garbage = 0;
+ unsigned long loose_size = 0;
+
+ for (i = 1; i < ac; i++) {
+ const char *arg = av[i];
+ if (*arg != '-')
+ break;
+ else if (!strcmp(arg, "-v"))
+ verbose = 1;
+ else
+ usage(count_objects_usage);
+ }
+
+ /* we do not take arguments other than flags for now */
+ if (i < ac)
+ usage(count_objects_usage);
+ memcpy(path, objdir, len);
+ if (len && objdir[len-1] != '/')
+ path[len++] = '/';
+ for (i = 0; i < 256; i++) {
+ DIR *d;
+ sprintf(path + len, "%02x", i);
+ d = opendir(path);
+ if (!d)
+ continue;
+ count_objects(d, path, len, verbose,
+ &loose, &loose_size, &packed_loose, &garbage);
+ closedir(d);
+ }
+ if (verbose) {
+ struct packed_git *p;
+ if (!packed_git)
+ prepare_packed_git();
+ for (p = packed_git; p; p = p->next) {
+ if (!p->pack_local)
+ continue;
+ packed += num_packed_objects(p);
+ }
+ printf("count: %lu\n", loose);
+ printf("size: %lu\n", loose_size / 2);
+ printf("in-pack: %lu\n", packed);
+ printf("prune-packable: %lu\n", packed_loose);
+ printf("garbage: %lu\n", garbage);
+ }
+ else
+ printf("%lu objects, %lu kilobytes\n",
+ loose, loose_size / 2);
+ return 0;
+}
diff --git a/builtin-push.c b/builtin-push.c
new file mode 100644
index 000000000..06d06ff31
--- /dev/null
+++ b/builtin-push.c
@@ -0,0 +1,312 @@
+/*
+ * "git push"
+ */
+#include "cache.h"
+#include "refs.h"
+#include "run-command.h"
+#include "builtin.h"
+
+#define MAX_URI (16)
+
+static const char push_usage[] = "git push [--all] [--tags] [--force] <repository> [<refspec>...]";
+
+static int all = 0, tags = 0, force = 0, thin = 1;
+static const char *execute = NULL;
+
+#define BUF_SIZE (2084)
+static char buffer[BUF_SIZE];
+
+static const char **refspec = NULL;
+static int refspec_nr = 0;
+
+static void add_refspec(const char *ref)
+{
+ int nr = refspec_nr + 1;
+ refspec = xrealloc(refspec, nr * sizeof(char *));
+ refspec[nr-1] = ref;
+ refspec_nr = nr;
+}
+
+static int expand_one_ref(const char *ref, const unsigned char *sha1)
+{
+ /* Ignore the "refs/" at the beginning of the refname */
+ ref += 5;
+
+ if (strncmp(ref, "tags/", 5))
+ return 0;
+
+ add_refspec(strdup(ref));
+ return 0;
+}
+
+static void expand_refspecs(void)
+{
+ if (all) {
+ if (refspec_nr)
+ die("cannot mix '--all' and a refspec");
+
+ /*
+ * No need to expand "--all" - we'll just use
+ * the "--all" flag to send-pack
+ */
+ return;
+ }
+ if (!tags)
+ return;
+ for_each_ref(expand_one_ref);
+}
+
+static void set_refspecs(const char **refs, int nr)
+{
+ if (nr) {
+ size_t bytes = nr * sizeof(char *);
+
+ refspec = xrealloc(refspec, bytes);
+ memcpy(refspec, refs, bytes);
+ refspec_nr = nr;
+ }
+ expand_refspecs();
+}
+
+static int get_remotes_uri(const char *repo, const char *uri[MAX_URI])
+{
+ int n = 0;
+ FILE *f = fopen(git_path("remotes/%s", repo), "r");
+ int has_explicit_refspec = refspec_nr;
+
+ if (!f)
+ return -1;
+ while (fgets(buffer, BUF_SIZE, f)) {
+ int is_refspec;
+ char *s, *p;
+
+ if (!strncmp("URL: ", buffer, 5)) {
+ is_refspec = 0;
+ s = buffer + 5;
+ } else if (!strncmp("Push: ", buffer, 6)) {
+ is_refspec = 1;
+ s = buffer + 6;
+ } else
+ continue;
+
+ /* Remove whitespace at the head.. */
+ while (isspace(*s))
+ s++;
+ if (!*s)
+ continue;
+
+ /* ..and at the end */
+ p = s + strlen(s);
+ while (isspace(p[-1]))
+ *--p = 0;
+
+ if (!is_refspec) {
+ if (n < MAX_URI)
+ uri[n++] = strdup(s);
+ else
+ error("more than %d URL's specified, ignoreing the rest", MAX_URI);
+ }
+ else if (is_refspec && !has_explicit_refspec)
+ add_refspec(strdup(s));
+ }
+ fclose(f);
+ if (!n)
+ die("remote '%s' has no URL", repo);
+ return n;
+}
+
+static const char **config_uri;
+static const char *config_repo;
+static int config_repo_len;
+static int config_current_uri;
+static int config_get_refspecs;
+
+static int get_remote_config(const char* key, const char* value)
+{
+ if (!strncmp(key, "remote.", 7) &&
+ !strncmp(key + 7, config_repo, config_repo_len)) {
+ if (!strcmp(key + 7 + config_repo_len, ".url")) {
+ if (config_current_uri < MAX_URI)
+ config_uri[config_current_uri++] = strdup(value);
+ else
+ error("more than %d URL's specified, ignoring the rest", MAX_URI);
+ }
+ else if (config_get_refspecs &&
+ !strcmp(key + 7 + config_repo_len, ".push"))
+ add_refspec(strdup(value));
+ }
+ return 0;
+}
+
+static int get_config_remotes_uri(const char *repo, const char *uri[MAX_URI])
+{
+ config_repo_len = strlen(repo);
+ config_repo = repo;
+ config_current_uri = 0;
+ config_uri = uri;
+ config_get_refspecs = !refspec_nr;
+
+ git_config(get_remote_config);
+ return config_current_uri;
+}
+
+static int get_branches_uri(const char *repo, const char *uri[MAX_URI])
+{
+ const char *slash = strchr(repo, '/');
+ int n = slash ? slash - repo : 1000;
+ FILE *f = fopen(git_path("branches/%.*s", n, repo), "r");
+ char *s, *p;
+ int len;
+
+ if (!f)
+ return 0;
+ s = fgets(buffer, BUF_SIZE, f);
+ fclose(f);
+ if (!s)
+ return 0;
+ while (isspace(*s))
+ s++;
+ if (!*s)
+ return 0;
+ p = s + strlen(s);
+ while (isspace(p[-1]))
+ *--p = 0;
+ len = p - s;
+ if (slash)
+ len += strlen(slash);
+ p = xmalloc(len + 1);
+ strcpy(p, s);
+ if (slash)
+ strcat(p, slash);
+ uri[0] = p;
+ return 1;
+}
+
+/*
+ * Read remotes and branches file, fill the push target URI
+ * list. If there is no command line refspecs, read Push: lines
+ * to set up the *refspec list as well.
+ * return the number of push target URIs
+ */
+static int read_config(const char *repo, const char *uri[MAX_URI])
+{
+ int n;
+
+ if (*repo != '/') {
+ n = get_remotes_uri(repo, uri);
+ if (n > 0)
+ return n;
+
+ n = get_config_remotes_uri(repo, uri);
+ if (n > 0)
+ return n;
+
+ n = get_branches_uri(repo, uri);
+ if (n > 0)
+ return n;
+ }
+
+ uri[0] = repo;
+ return 1;
+}
+
+static int do_push(const char *repo)
+{
+ const char *uri[MAX_URI];
+ int i, n;
+ int remote;
+ const char **argv;
+ int argc;
+
+ n = read_config(repo, uri);
+ if (n <= 0)
+ die("bad repository '%s'", repo);
+
+ argv = xmalloc((refspec_nr + 10) * sizeof(char *));
+ argv[0] = "dummy-send-pack";
+ argc = 1;
+ if (all)
+ argv[argc++] = "--all";
+ if (force)
+ argv[argc++] = "--force";
+ if (execute)
+ argv[argc++] = execute;
+ if (thin)
+ argv[argc++] = "--thin";
+ remote = argc;
+ argv[argc++] = "dummy-remote";
+ while (refspec_nr--)
+ argv[argc++] = *refspec++;
+ argv[argc] = NULL;
+
+ for (i = 0; i < n; i++) {
+ int error;
+ const char *dest = uri[i];
+ const char *sender = "git-send-pack";
+ if (!strncmp(dest, "http://", 7) ||
+ !strncmp(dest, "https://", 8))
+ sender = "git-http-push";
+ argv[0] = sender;
+ argv[remote] = dest;
+ error = run_command_v(argc, argv);
+ if (!error)
+ continue;
+ switch (error) {
+ case -ERR_RUN_COMMAND_FORK:
+ die("unable to fork for %s", sender);
+ case -ERR_RUN_COMMAND_EXEC:
+ die("unable to exec %s", sender);
+ case -ERR_RUN_COMMAND_WAITPID:
+ case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
+ case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
+ case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
+ die("%s died with strange error", sender);
+ default:
+ return -error;
+ }
+ }
+ return 0;
+}
+
+int cmd_push(int argc, const char **argv, char **envp)
+{
+ int i;
+ const char *repo = "origin"; // default repository
+
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+
+ if (arg[0] != '-') {
+ repo = arg;
+ i++;
+ break;
+ }
+ if (!strcmp(arg, "--all")) {
+ all = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--tags")) {
+ tags = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--force")) {
+ force = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--thin")) {
+ thin = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--no-thin")) {
+ thin = 0;
+ continue;
+ }
+ if (!strncmp(arg, "--exec=", 7)) {
+ execute = arg;
+ continue;
+ }
+ usage(push_usage);
+ }
+ set_refspecs(argv + i, argc - i);
+ return do_push(repo);
+}
diff --git a/builtin.h b/builtin.h
index 47408a058..dca69632d 100644
--- a/builtin.h
+++ b/builtin.h
@@ -19,5 +19,8 @@ extern int cmd_version(int argc, const char **argv, char **envp);
extern int cmd_whatchanged(int argc, const char **argv, char **envp);
extern int cmd_show(int argc, const char **argv, char **envp);
extern int cmd_log(int argc, const char **argv, char **envp);
+extern int cmd_count_objects(int argc, const char **argv, char **envp);
+
+extern int cmd_push(int argc, const char **argv, char **envp);
#endif
diff --git a/diff.c b/diff.c
index 6762fcee5..c845c8711 100644
--- a/diff.c
+++ b/diff.c
@@ -1018,14 +1018,12 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
}
if (memcmp(one->sha1, two->sha1, 20)) {
- char one_sha1[41];
int abbrev = o->full_index ? 40 : DEFAULT_ABBREV;
- memcpy(one_sha1, sha1_to_hex(one->sha1), 41);
len += snprintf(msg + len, sizeof(msg) - len,
"index %.*s..%.*s",
- abbrev, one_sha1, abbrev,
- sha1_to_hex(two->sha1));
+ abbrev, sha1_to_hex(one->sha1),
+ abbrev, sha1_to_hex(two->sha1));
if (one->mode == two->mode)
len += snprintf(msg + len, sizeof(msg) - len,
" %06o", one->mode);
diff --git a/git-count-objects.sh b/git-count-objects.sh
deleted file mode 100755
index 40c58efe0..000000000
--- a/git-count-objects.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Junio C Hamano
-#
-
-GIT_DIR=`git-rev-parse --git-dir` || exit $?
-
-dc </dev/null 2>/dev/null || {
- # This is not a real DC at all -- it just knows how
- # this script feeds DC and does the computation itself.
- dc () {
- while read a b
- do
- case $a,$b in
- 0,) acc=0 ;;
- *,+) acc=$(($acc + $a)) ;;
- p,) echo "$acc" ;;
- esac
- done
- }
-}
-
-echo $(find "$GIT_DIR/objects"/?? -type f -print 2>/dev/null | wc -l) objects, \
-$({
- echo 0
- # "no-such" is to help Darwin folks by not using xargs -r.
- find "$GIT_DIR/objects"/?? -type f -print 2>/dev/null |
- xargs du -k "$GIT_DIR/objects/no-such" 2>/dev/null |
- sed -e 's/[ ].*/ +/'
- echo p
-} | dc) kilobytes
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
index 11d153c4c..ffd9c66f9 100755
--- a/git-cvsserver.perl
+++ b/git-cvsserver.perl
@@ -2076,14 +2076,15 @@ sub update
# TODO: log processing is memory bound
# if we can parse into a 2nd file that is in reverse order
# we can probably do something really efficient
- my @git_log_params = ('--parents', '--topo-order');
+ my @git_log_params = ('--pretty', '--parents', '--topo-order');
if (defined $lastcommit) {
push @git_log_params, "$lastcommit..$self->{module}";
} else {
push @git_log_params, $self->{module};
}
- open(GITLOG, '-|', 'git-log', @git_log_params) or die "Cannot call git-log: $!";
+ # git-rev-list is the backend / plumbing version of git-log
+ open(GITLOG, '-|', 'git-rev-list', @git_log_params) or die "Cannot call git-rev-list: $!";
my @commits;
diff --git a/git.c b/git.c
index 01b7e28b8..4d3a5a30a 100644
--- a/git.c
+++ b/git.c
@@ -46,6 +46,8 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "log", cmd_log },
{ "whatchanged", cmd_whatchanged },
{ "show", cmd_show },
+ { "push", cmd_push },
+ { "count-objects", cmd_count_objects },
};
int i;
diff --git a/log-tree.c b/log-tree.c
index 9634c4677..b90ba6762 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -3,6 +3,15 @@
#include "commit.h"
#include "log-tree.h"
+static void show_parents(struct commit *commit, int abbrev)
+{
+ struct commit_list *p;
+ for (p = commit->parents; p ; p = p->next) {
+ struct commit *parent = p->item;
+ printf(" %s", diff_unique_abbrev(parent->object.sha1, abbrev));
+ }
+}
+
void show_log(struct rev_info *opt, struct log_info *log, const char *sep)
{
static char this_header[16384];
@@ -14,7 +23,10 @@ void show_log(struct rev_info *opt, struct log_info *log, const char *sep)
opt->loginfo = NULL;
if (!opt->verbose_header) {
- puts(sha1_to_hex(commit->object.sha1));
+ fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), stdout);
+ if (opt->parents)
+ show_parents(commit, abbrev_commit);
+ putchar('\n');
return;
}
@@ -40,7 +52,9 @@ void show_log(struct rev_info *opt, struct log_info *log, const char *sep)
printf("%s%s",
opt->commit_format == CMIT_FMT_ONELINE ? "" : "commit ",
diff_unique_abbrev(commit->object.sha1, abbrev_commit));
- if (parent)
+ if (opt->parents)
+ show_parents(commit, abbrev_commit);
+ if (parent)
printf(" (from %s)", diff_unique_abbrev(parent->object.sha1, abbrev_commit));
putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n');
diff --git a/merge-tree.c b/merge-tree.c
index 50528d5e4..cc7b5bd89 100644
--- a/merge-tree.c
+++ b/merge-tree.c
@@ -24,16 +24,14 @@ static const char *sha1_to_hex_zero(const unsigned char *sha1)
static void resolve(const char *base, struct name_entry *branch1, struct name_entry *result)
{
- char branch1_sha1[50];
-
/* If it's already branch1, don't bother showing it */
if (!branch1)
return;
- memcpy(branch1_sha1, sha1_to_hex_zero(branch1->sha1), 41);
printf("0 %06o->%06o %s->%s %s%s\n",
branch1->mode, result->mode,
- branch1_sha1, sha1_to_hex_zero(result->sha1),
+ sha1_to_hex_zero(branch1->sha1),
+ sha1_to_hex_zero(result->sha1),
base, result->path);
}
diff --git a/revision.c b/revision.c
index ad78efda5..c6e8702f3 100644
--- a/revision.c
+++ b/revision.c
@@ -574,7 +574,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
revs->max_count = atoi(arg + 12);
continue;
}
- /* accept -<digit>, like traditilnal "head" */
+ /* accept -<digit>, like traditional "head" */
if ((*arg == '-') && isdigit(arg[1])) {
revs->max_count = atoi(arg + 1);
continue;
diff --git a/sha1_file.c b/sha1_file.c
index f2d33afb2..546482825 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -108,9 +108,10 @@ int safe_create_leading_directories(char *path)
char * sha1_to_hex(const unsigned char *sha1)
{
- static char buffer[50];
+ static int bufno;
+ static char hexbuffer[4][50];
static const char hex[] = "0123456789abcdef";
- char *buf = buffer;
+ char *buffer = hexbuffer[3 & ++bufno], *buf = buffer;
int i;
for (i = 0; i < 20; i++) {
diff --git a/update-index.c b/update-index.c
index facec8d91..9fa3d2bb9 100644
--- a/update-index.c
+++ b/update-index.c
@@ -473,7 +473,7 @@ static void read_index_info(int line_termination)
}
static const char update_index_usage[] =
-"git-update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--cacheinfo] [--chmod=(+|-)x] [--info-only] [--force-remove] [--stdin] [--index-info] [--ignore-missing] [-z] [--verbose] [--] <file>...";
+"git-update-index [-q] [--add] [--replace] [--remove] [--unmerged] [--refresh] [--really-refresh] [--cacheinfo] [--chmod=(+|-)x] [--assume-unchanged] [--info-only] [--force-remove] [--stdin] [--index-info] [--unresolve] [--ignore-missing] [-z] [--verbose] [--] <file>...";
static unsigned char head_sha1[20];
static unsigned char merge_head_sha1[20];