Merge branch 'master' into next

* master:
  fsck-objects: refactor checking for connectivity
  git-gc: do not run git-prune by default.
  shallow repository: disable unsupported operations for now.
  is_repository_shallow(): prototype fix.
  Make sure git_connect() always give two file descriptors.
  Revert "prune: --grace=time"
  Documentation/tutorial-2: Fix interesting typo in an example.
This commit is contained in:
Junio C Hamano
2007-01-22 00:12:22 -08:00
16 changed files with 150 additions and 95 deletions

View File

@@ -8,7 +8,7 @@ git-gc - Cleanup unnecessary files and optimize the local repository
SYNOPSIS
--------
'git-gc'
'git-gc' [--prune]
DESCRIPTION
-----------
@@ -21,6 +21,21 @@ Users are encouraged to run this task on a regular basis within
each repository to maintain good disk space utilization and good
operating performance.
OPTIONS
-------
--prune::
Usually `git-gc` packs refs, expires old reflog entries,
packs loose objects,
and removes old 'rerere' records. Removal
of unreferenced loose objects is an unsafe operation
while other git operations are in progress, so it is not
done by default. Pass this option if you want it, and only
when you know nobody else is creating new objects in the
repository at the same time (e.g. never use this option
in a cron script).
Configuration
-------------

View File

@@ -8,7 +8,7 @@ git-prune - Prunes all unreachable objects from the object database
SYNOPSIS
--------
'git-prune' [-n] [--grace=<time>]
'git-prune' [-n] [--] [<head>...]
DESCRIPTION
-----------
@@ -28,12 +28,6 @@ OPTIONS
Do not remove anything; just report what it would
remove.
--grace=<time>::
Do not prune loose objects that are younger than the
specified time. This gives a grace period to newly
created objects from getting pruned.
////////////////////////////////////////////
\--::
Do not interpret any more arguments as options.
@@ -52,7 +46,6 @@ borrows from your repository via its
------------
$ git prune $(cd ../another && $(git-rev-parse --all))
------------
////////////////////////////////////////////
Author
------

View File

@@ -343,8 +343,8 @@ And, as you can see with cat-file, this new entry refers to the
current contents of the file:
------------------------------------------------
$ git cat-file blob a6b11f7a
goodbye, word
$ git cat-file blob 8b9743b2
goodbye, world
------------------------------------------------
The "status" command is a useful way to get a quick summary of the

View File

@@ -74,6 +74,7 @@ static int run_remote_archiver(const char *remote, int argc,
/* Now, start reading from fd[0] and spit it out to stdout */
rv = recv_sideband("archive", fd[0], 1, 2);
close(fd[0]);
close(fd[1]);
rv |= finish_connect(pid);
return !!rv;

View File

@@ -5,9 +5,8 @@
#include "builtin.h"
#include "reachable.h"
static const char prune_usage[] = "git-prune [-n] [--grace=time]";
static const char prune_usage[] = "git-prune [-n]";
static int show_only;
static int prune_grace_period;
static int prune_object(char *path, const char *filename, const unsigned char *sha1)
{
@@ -39,7 +38,6 @@ static int prune_dir(int i, char *path)
char name[100];
unsigned char sha1[20];
int len = strlen(de->d_name);
struct stat st;
switch (len) {
case 2:
@@ -62,11 +60,6 @@ static int prune_dir(int i, char *path)
if (lookup_object(sha1))
continue;
if (prune_grace_period > 0 &&
!stat(mkpath("%s/%s", path, de->d_name), &st) &&
st.st_mtime > prune_grace_period)
continue;
prune_object(path, de->d_name, sha1);
continue;
}
@@ -86,25 +79,10 @@ static void prune_object_dir(const char *path)
}
}
static int git_prune_config(const char *var, const char *value)
{
if (!strcmp(var, "gc.prunegrace")) {
if (!strcmp(value, "off"))
prune_grace_period = 0;
else
prune_grace_period = approxidate(value);
return 0;
}
return git_default_config(var, value);
}
int cmd_prune(int argc, const char **argv, const char *prefix)
{
int i;
struct rev_info revs;
prune_grace_period = time(NULL)-24*60*60;
git_config(git_prune_config);
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
@@ -112,13 +90,6 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
show_only = 1;
continue;
}
if (!strncmp(arg, "--grace=", 8)) {
if (!strcmp(arg+8, "off"))
prune_grace_period = 0;
else
prune_grace_period = approxidate(arg+8);
continue;
}
usage(prune_usage);
}

View File

@@ -110,7 +110,7 @@ extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *r
extern int register_shallow(const unsigned char *sha1);
extern int unregister_shallow(const unsigned char *sha1);
extern int write_shallow_commits(int fd, int use_pack_protocol);
extern int is_repository_shallow();
extern int is_repository_shallow(void);
extern struct commit_list *get_shallow_commits(struct object_array *heads,
int depth, int shallow_flag, int not_shallow_flag);

View File

@@ -529,7 +529,7 @@ static void git_tcp_connect(int fd[2], char *host)
int sockfd = git_tcp_connect_sock(host);
fd[0] = sockfd;
fd[1] = sockfd;
fd[1] = dup(sockfd);
}

View File

@@ -54,6 +54,99 @@ static int objwarning(struct object *obj, const char *err, ...)
return -1;
}
/*
* Check a single reachable object
*/
static void check_reachable_object(struct object *obj)
{
const struct object_refs *refs;
/*
* We obviously want the object to be parsed,
* except if it was in a pack-file and we didn't
* do a full fsck
*/
if (!obj->parsed) {
if (has_sha1_file(obj->sha1))
return; /* it is in pack - forget about it */
printf("missing %s %s\n", typename(obj->type), sha1_to_hex(obj->sha1));
return;
}
/*
* Check that everything that we try to reference is also good.
*/
refs = lookup_object_refs(obj);
if (refs) {
unsigned j;
for (j = 0; j < refs->count; j++) {
struct object *ref = refs->ref[j];
if (ref->parsed ||
(has_sha1_file(ref->sha1)))
continue;
printf("broken link from %7s %s\n",
typename(obj->type), sha1_to_hex(obj->sha1));
printf(" to %7s %s\n",
typename(ref->type), sha1_to_hex(ref->sha1));
}
}
}
/*
* Check a single unreachable object
*/
static void check_unreachable_object(struct object *obj)
{
/*
* Missing unreachable object? Ignore it. It's not like
* we miss it (since it can't be reached), nor do we want
* to complain about it being unreachable (since it does
* not exist).
*/
if (!obj->parsed)
return;
/*
* Unreachable object that exists? Show it if asked to,
* since this is something that is prunable.
*/
if (show_unreachable) {
printf("unreachable %s %s\n", typename(obj->type), sha1_to_hex(obj->sha1));
return;
}
/*
* "!used" means that nothing at all points to it, including
* other unreacahble objects. In other words, it's the "tip"
* of some set of unreachable objects, usually a commit that
* got dropped.
*
* Such starting points are more interesting than some random
* set of unreachable objects, so we show them even if the user
* hasn't asked for _all_ unreachable objects. If you have
* deleted a branch by mistake, this is a prime candidate to
* start looking at, for example.
*/
if (!obj->used) {
printf("dangling %s %s\n", typename(obj->type),
sha1_to_hex(obj->sha1));
return;
}
/*
* Otherwise? It's there, it's unreachable, and some other unreachable
* object points to it. Ignore it - it's not interesting, and we showed
* all the interesting cases above.
*/
}
static void check_object(struct object *obj)
{
if (obj->flags & REACHABLE)
check_reachable_object(obj);
else
check_unreachable_object(obj);
}
static void check_connectivity(void)
{
@@ -62,46 +155,10 @@ static void check_connectivity(void)
/* Look up all the requirements, warn about missing objects.. */
max = get_max_object_index();
for (i = 0; i < max; i++) {
const struct object_refs *refs;
struct object *obj = get_indexed_object(i);
if (!obj)
continue;
if (!obj->parsed) {
if (has_sha1_file(obj->sha1))
; /* it is in pack */
else
printf("missing %s %s\n",
typename(obj->type), sha1_to_hex(obj->sha1));
continue;
}
refs = lookup_object_refs(obj);
if (refs) {
unsigned j;
for (j = 0; j < refs->count; j++) {
struct object *ref = refs->ref[j];
if (ref->parsed ||
(has_sha1_file(ref->sha1)))
continue;
printf("broken link from %7s %s\n",
typename(obj->type), sha1_to_hex(obj->sha1));
printf(" to %7s %s\n",
typename(ref->type), sha1_to_hex(ref->sha1));
}
}
if (show_unreachable && !(obj->flags & REACHABLE)) {
printf("unreachable %s %s\n",
typename(obj->type), sha1_to_hex(obj->sha1));
continue;
}
if (!obj->used) {
printf("dangling %s %s\n", typename(obj->type),
sha1_to_hex(obj->sha1));
}
if (obj)
check_object(obj);
}
}

View File

@@ -4,12 +4,26 @@
#
# Cleanup unreachable files and optimize the repository.
USAGE=''
USAGE='git-gc [--prune]'
SUBDIRECTORY_OK=Yes
. git-sh-setup
no_prune=:
while case $# in 0) break ;; esac
do
case "$1" in
--prune)
no_prune=
;;
--)
usage
;;
esac
shift
done
git-pack-refs --prune &&
git-reflog expire --all &&
git-repack -a -d -l &&
git-prune &&
$no_prune git-prune &&
git-rerere gc || exit

View File

@@ -421,6 +421,9 @@ int main(int argc, char **argv)
if(!enter_repo(dir, 0))
die("'%s': unable to chdir or not a git archive", dir);
if (is_repository_shallow())
die("attempt to push into a shallow repository");
setup_ident();
/* don't die if gecos is empty */
ignore_missing_committer_name();

View File

@@ -17,7 +17,7 @@ int register_shallow(const unsigned char *sha1)
return register_commit_graft(graft, 0);
}
int is_repository_shallow()
int is_repository_shallow(void)
{
FILE *fp;
char buf[1024];

View File

@@ -96,7 +96,7 @@ test_expect_success setup '
check_have A B C D E F G H I J K L &&
git prune --grace=off &&
git prune &&
check_have A B C D E F G H I J K L &&
@@ -115,7 +115,7 @@ test_expect_success rewind '
check_have A B C D E F G H I J K L &&
git prune --grace=off &&
git prune &&
check_have A B C D E F G H I J K L &&
@@ -160,7 +160,7 @@ test_expect_success 'reflog expire' '
test_expect_success 'prune and fsck' '
git prune --grace=off &&
git prune &&
check_fsck &&
check_have A B C D E H L &&

View File

@@ -55,13 +55,13 @@ test_expect_success setup '
test_expect_success 'pack the source repository' '
git repack -a -d &&
git prune --grace=off
git prune
'
test_expect_success 'pack the destination repository' '
cd victim &&
git repack -a -d &&
git prune --grace=off &&
git prune &&
cd ..
'

View File

@@ -22,7 +22,7 @@ echo second > file2 &&
git add file2 &&
git commit -m addition &&
git repack -a -d &&
git prune --grace=off'
git prune'
cd "$base_dir"
@@ -56,7 +56,7 @@ echo third > file3 &&
git add file3 &&
git commit -m update &&
git repack -a -d &&
git prune --grace=off'
git prune'
cd "$base_dir"

View File

@@ -29,7 +29,7 @@ echo "Hello World" > file1 &&
git add file1 &&
git commit -m "Initial commit" file1 &&
git repack -a -d &&
git prune --grace=off'
git prune'
cd "$base_dir"
@@ -39,7 +39,7 @@ echo "foo bar" > file2 &&
git add file2 &&
git commit -m "next commit" file2 &&
git repack -a -d -l &&
git prune --grace=off'
git prune'
cd "$base_dir"
@@ -49,7 +49,7 @@ echo "Goodbye, cruel world" > file3 &&
git add file3 &&
git commit -m "one more" file3 &&
git repack -a -d -l &&
git prune --grace=off'
git prune'
cd "$base_dir"

View File

@@ -672,7 +672,8 @@ int main(int argc, char **argv)
if (!enter_repo(dir, strict))
die("'%s': unable to chdir or not a git archive", dir);
if (is_repository_shallow())
die("attempt to fetch/clone from a shallow repository");
upload_pack();
return 0;
}