mirror of
https://github.com/git/git.git
synced 2026-03-13 18:33:25 +01:00
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:
@@ -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
|
||||
-------------
|
||||
|
||||
|
||||
@@ -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
|
||||
------
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
2
commit.h
2
commit.h
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
133
fsck-objects.c
133
fsck-objects.c
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
18
git-gc.sh
18
git-gc.sh
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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 ..
|
||||
'
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user