mirror of
https://github.com/git/git.git
synced 2026-03-13 18:33:25 +01:00
Merge branch 'master' into next
* master: Remove unnecessary found variable from describe. Use inttypes.h rather than stdint.h. Documentation: pack-refs --all vs default behaviour show-branch -g: default to HEAD Add dangling objects tips. parse-remote: do not barf on a remote shorthand without any refs to fetch. diffcore-pickaxe: fix infinite loop on zero-length needle Allow non-developer to clone, checkout and fetch more easily. contrib/emacs/vc-git.el: support vc-version-other-window Fix seriously broken "git pack-refs" New files in git weren't being downloaded during CVS update make --upload-pack option to git-fetch configurable
This commit is contained in:
@@ -429,9 +429,13 @@ remote.<name>.push::
|
||||
gitlink:git-push[1].
|
||||
|
||||
remote.<name>.receivepack::
|
||||
The default program to execute on the remote side when pulling. See
|
||||
The default program to execute on the remote side when pushing. See
|
||||
option \--exec of gitlink:git-push[1].
|
||||
|
||||
remote.<name>.uploadpack::
|
||||
The default program to execute on the remote side when fetching. See
|
||||
option \--exec of gitlink:git-fetch-pack[1].
|
||||
|
||||
repack.usedeltabaseoffset::
|
||||
Allow gitlink:git-repack[1] to create packs that uses
|
||||
delta-base offset. Defaults to false.
|
||||
|
||||
@@ -29,12 +29,23 @@ file and used if found.
|
||||
Subsequent updates to branches always creates new file under
|
||||
`$GIT_DIR/refs` hierarchy.
|
||||
|
||||
A recommended practice to deal with a repository with too many
|
||||
refs is to pack its refs with `--all --prune` once, and
|
||||
occasionally run `git-pack-refs \--prune`. Tags are by
|
||||
definition stationary and are not expected to change. Branch
|
||||
heads will be packed with the initial `pack-refs --all`, but
|
||||
only the currently active branch heads will become unpacked,
|
||||
and next `pack-refs` (without `--all`) will leave them
|
||||
unpacked.
|
||||
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
\--all::
|
||||
|
||||
The command by default packs all tags and leaves branch tips
|
||||
The command by default packs all tags and refs that are already
|
||||
packed, and leaves other refs
|
||||
alone. This is because branches are expected to be actively
|
||||
developed and packing their tips does not help performance.
|
||||
This option causes branch tips to be packed as well. Useful for
|
||||
|
||||
109
Documentation/howto/dangling-objects.txt
Normal file
109
Documentation/howto/dangling-objects.txt
Normal file
@@ -0,0 +1,109 @@
|
||||
From: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Subject: Re: Question about fsck-objects output
|
||||
Date: Thu, 25 Jan 2007 12:01:06 -0800 (PST)
|
||||
Message-ID: <Pine.LNX.4.64.0701251144290.25027@woody.linux-foundation.org>
|
||||
Archived-At: <http://permalink.gmane.org/gmane.comp.version-control.git/37754>
|
||||
Abstract: Linus describes what dangling objects are, when they
|
||||
are left behind, and how to view their relationship with branch
|
||||
heads in gitk
|
||||
|
||||
On Thu, 25 Jan 2007, Larry Streepy wrote:
|
||||
|
||||
> Sorry to ask such a basic question, but I can't quite decipher the output of
|
||||
> fsck-objects. When I run it, I get this:
|
||||
>
|
||||
> git fsck-objects
|
||||
> dangling commit 2213f6d4dd39ca8baebd0427723723e63208521b
|
||||
> dangling commit f0d4e00196bd5ee54463e9ea7a0f0e8303da767f
|
||||
> dangling blob 6a6d0b01b3e96d49a8f2c7addd4ef8c3bd1f5761
|
||||
>
|
||||
>
|
||||
> Even after a "repack -a -d" they still exist. The man page has a short
|
||||
> explanation, but, at least for me, it wasn't fully enlightening. :-)
|
||||
>
|
||||
> The man page says that dangling commits could be "root" commits, but since my
|
||||
> repo started as a clone of another repo, I don't see how I could have any root
|
||||
> commits. Also, the page doesn't really describe what a dangling blob is.
|
||||
>
|
||||
> So, can someone explain what these artifacts are and if they are a problem
|
||||
> that I should be worried about?
|
||||
|
||||
The most common situation is that you've rebased a branch (or you have
|
||||
pulled from somebody else who rebased a branch, like the "pu" branch in
|
||||
the git.git archive itself).
|
||||
|
||||
What happens is that the old head of the original branch still exists, as
|
||||
does obviously everything it pointed to. The branch pointer itself just
|
||||
doesn't, since you replaced it with another one.
|
||||
|
||||
However, there are certainly other situations too that cause dangling
|
||||
objects. For example, the "dangling blob" situation you have tends to be
|
||||
because you did a "git add" of a file, but then, before you actually
|
||||
committed it and made it part of the bigger picture, you changed something
|
||||
else in that file and committed that *updated* thing - the old state that
|
||||
you added originally ends up not being pointed to by any commit/tree, so
|
||||
it's now a dangling blob object.
|
||||
|
||||
Similarly, when the "recursive" merge strategy runs, and finds that there
|
||||
are criss-cross merges and thus more than one merge base (which is fairly
|
||||
unusual, but it does happen), it will generate one temporary midway tree
|
||||
(or possibly even more, if you had lots of criss-crossing merges and
|
||||
more than two merge bases) as a temporary internal merge base, and again,
|
||||
those are real objects, but the end result will not end up pointing to
|
||||
them, so they end up "dangling" in your repository.
|
||||
|
||||
Generally, dangling objects aren't anything to worry about. They can even
|
||||
be very useful: if you screw something up, the dangling objects can be how
|
||||
you recover your old tree (say, you did a rebase, and realized that you
|
||||
really didn't want to - you can look at what dangling objects you have,
|
||||
and decide to reset your head to some old dangling state).
|
||||
|
||||
For commits, the most useful thing to do with dangling objects tends to be
|
||||
to do a simple
|
||||
|
||||
gitk <dangling-commit-sha-goes-here> --not --all
|
||||
|
||||
which means exactly what it sounds like: it says that you want to see the
|
||||
commit history that is described by the dangling commit(s), but you do NOT
|
||||
want to see the history that is described by all your branches and tags
|
||||
(which are the things you normally reach). That basically shows you in a
|
||||
nice way what the danglign commit was (and notice that it might not be
|
||||
just one commit: we only report the "tip of the line" as being dangling,
|
||||
but there might be a whole deep and complex commit history that has gotten
|
||||
dropped - rebasing will do that).
|
||||
|
||||
For blobs and trees, you can't do the same, but you can examine them. You
|
||||
can just do
|
||||
|
||||
git show <dangling-blob/tree-sha-goes-here>
|
||||
|
||||
to show what the contents of the blob were (or, for a tree, basically what
|
||||
the "ls" for that directory was), and that may give you some idea of what
|
||||
the operation was that left that dangling object.
|
||||
|
||||
Usually, dangling blobs and trees aren't very interesting. They're almost
|
||||
always the result of either being a half-way mergebase (the blob will
|
||||
often even have the conflict markers from a merge in it, if you have had
|
||||
conflicting merges that you fixed up by hand), or simply because you
|
||||
interrupted a "git fetch" with ^C or something like that, leaving _some_
|
||||
of the new objects in the object database, but just dangling and useless.
|
||||
|
||||
Anyway, once you are sure that you're not interested in any dangling
|
||||
state, you can just prune all unreachable objects:
|
||||
|
||||
git prune
|
||||
|
||||
and they'll be gone. But you should only run "git prune" on a quiescent
|
||||
repository - it's kind of like doing a filesystem fsck recovery: you don't
|
||||
want to do that while the filesystem is mounted.
|
||||
|
||||
(The same is true of "git-fsck-objects" itself, btw - but since
|
||||
git-fsck-objects never actually *changes* the repository, it just reports
|
||||
on what it found, git-fsck-objects itself is never "dangerous" to run.
|
||||
Running it while somebody is actually changing the repository can cause
|
||||
confusing and scary messages, but it won't actually do anything bad. In
|
||||
contrast, running "git prune" while somebody is actively changing the
|
||||
repository is a *BAD* idea).
|
||||
|
||||
Linus
|
||||
|
||||
@@ -101,7 +101,6 @@ static void describe(const char *arg, int last_one)
|
||||
struct possible_tag all_matches[MAX_TAGS];
|
||||
unsigned int match_cnt = 0, annotated_cnt = 0, cur_match;
|
||||
unsigned long seen_commits = 0;
|
||||
int found = 0;
|
||||
|
||||
if (get_sha1(arg, sha1))
|
||||
die("Not a valid object name %s", arg);
|
||||
@@ -137,7 +136,7 @@ static void describe(const char *arg, int last_one)
|
||||
t->name = n;
|
||||
t->depth = seen_commits - 1;
|
||||
t->flag_within = 1u << match_cnt;
|
||||
t->found_order = found++;
|
||||
t->found_order = match_cnt;
|
||||
c->object.flags |= t->flag_within;
|
||||
if (n->prio == 2)
|
||||
annotated_cnt++;
|
||||
|
||||
@@ -352,7 +352,7 @@ static void get_patch_ids(struct rev_info *rev, struct diff_options *options, co
|
||||
|
||||
static void gen_message_id(char *dest, unsigned int length, char *base)
|
||||
{
|
||||
const char *committer = git_committer_info(1);
|
||||
const char *committer = git_committer_info(-1);
|
||||
const char *email_start = strrchr(committer, '<');
|
||||
const char *email_end = strrchr(committer, '>');
|
||||
if(!email_start || !email_end || email_start > email_end - 1)
|
||||
|
||||
@@ -37,7 +37,9 @@ static int handle_one_ref(const char *path, const unsigned char *sha1,
|
||||
if ((flags & REF_ISSYMREF))
|
||||
return 0;
|
||||
is_tag_ref = !strncmp(path, "refs/tags/", 10);
|
||||
if (!cb->all && !is_tag_ref)
|
||||
|
||||
/* ALWAYS pack refs that were already packed or are tags */
|
||||
if (!cb->all && !is_tag_ref && !(flags & REF_ISPACKED))
|
||||
return 0;
|
||||
|
||||
fprintf(cb->refs_file, "%s %s\n", sha1_to_hex(sha1), path);
|
||||
|
||||
@@ -662,13 +662,13 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
|
||||
}
|
||||
ac--; av++;
|
||||
|
||||
if (!!extra || !!reflog) {
|
||||
if (extra || reflog) {
|
||||
/* "listing" mode is incompatible with
|
||||
* independent nor merge-base modes.
|
||||
*/
|
||||
if (independent || merge_base)
|
||||
usage(show_branch_usage);
|
||||
if (!!reflog && ((0 < extra) || all_heads || all_remotes))
|
||||
if (reflog && ((0 < extra) || all_heads || all_remotes))
|
||||
/*
|
||||
* Asking for --more in reflog mode does not
|
||||
* make sense. --list is Ok.
|
||||
@@ -682,15 +682,22 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
|
||||
if (ac + all_heads + all_remotes == 0)
|
||||
all_heads = 1;
|
||||
|
||||
if (all_heads + all_remotes)
|
||||
snarf_refs(all_heads, all_remotes);
|
||||
if (reflog) {
|
||||
unsigned char sha1[20];
|
||||
char nth_desc[256];
|
||||
char *ref;
|
||||
int base = 0;
|
||||
|
||||
if (ac == 0) {
|
||||
static const char *fake_av[2];
|
||||
fake_av[0] = "HEAD";
|
||||
fake_av[1] = NULL;
|
||||
av = fake_av;
|
||||
ac = 1;
|
||||
}
|
||||
if (ac != 1)
|
||||
die("--reflog option needs one branch name");
|
||||
|
||||
if (MAX_REVS < reflog)
|
||||
die("Only %d entries can be shown at one time.",
|
||||
MAX_REVS);
|
||||
@@ -735,6 +742,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
|
||||
append_ref(nth_desc, sha1, 1);
|
||||
}
|
||||
}
|
||||
else if (all_heads + all_remotes)
|
||||
snarf_refs(all_heads, all_remotes);
|
||||
else {
|
||||
while (0 < ac) {
|
||||
append_one_rev(*av);
|
||||
|
||||
1
cache.h
1
cache.h
@@ -320,7 +320,6 @@ void datestamp(char *buf, int bufsize);
|
||||
unsigned long approxidate(const char *);
|
||||
|
||||
extern int setup_ident(void);
|
||||
extern void ignore_missing_committer_name(void);
|
||||
extern const char *git_author_info(int);
|
||||
extern const char *git_committer_info(int);
|
||||
|
||||
|
||||
@@ -53,6 +53,10 @@
|
||||
(let ((name (file-relative-name file)))
|
||||
(eq 0 (apply #'call-process "git" nil (get-buffer "*Messages") nil (append args (list name))))))
|
||||
|
||||
(defun vc-git--run-command-out (output &rest args)
|
||||
"Run a git command, output to output."
|
||||
(eq 0 (apply #'call-process "git" nil output nil (append args))))
|
||||
|
||||
(defun vc-git-registered (file)
|
||||
"Check whether FILE is registered with git."
|
||||
(with-temp-buffer
|
||||
@@ -120,7 +124,28 @@
|
||||
(vc-git--run-command file "commit" "-m" comment "--only" "--")))
|
||||
|
||||
(defun vc-git-checkout (file &optional editable rev destfile)
|
||||
(vc-git--run-command file "checkout" (or rev "HEAD")))
|
||||
(if destfile
|
||||
(let ((mybuff (get-buffer-create "vc-git-checkout-tmp")))
|
||||
(let ((rv
|
||||
(vc-git--run-command-out
|
||||
mybuff "cat-file" "blob"
|
||||
(concat (or rev "HEAD")
|
||||
":"
|
||||
(let ((output (vc-git--run-command-string
|
||||
(file-relative-name file)
|
||||
"ls-files" "--full-name")))
|
||||
(string-match "\\(.*\\)" output)
|
||||
(match-string 1 output))
|
||||
)))
|
||||
)
|
||||
(if rv
|
||||
(save-current-buffer
|
||||
(set-buffer mybuff)
|
||||
(set-visited-file-name destfile t)
|
||||
(save-buffer)
|
||||
)
|
||||
rv)))
|
||||
(vc-git--run-command file "checkout" (or rev "HEAD"))))
|
||||
|
||||
(defun vc-git-annotate-command (file buf &optional rev)
|
||||
; FIXME: rev is ignored
|
||||
|
||||
@@ -14,6 +14,8 @@ static unsigned int contains(struct diff_filespec *one,
|
||||
const char *data;
|
||||
if (diff_populate_filespec(one, 0))
|
||||
return 0;
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
sz = one->size;
|
||||
data = one->data;
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
|
||||
#include <grp.h>
|
||||
#define _ALL_SOURCE 1
|
||||
|
||||
@@ -876,9 +876,9 @@ sub req_update
|
||||
print "MT newline\n";
|
||||
next;
|
||||
}
|
||||
elsif ( !defined($wrev) || $wrev == 0 )
|
||||
elsif ( (!defined($wrev) || $wrev == 0) && (!defined($meta->{revision}) || $meta->{revision} == 0) )
|
||||
{
|
||||
$log->info("Tell the client the file will be added");
|
||||
$log->info("Tell the client the file is scheduled for addition");
|
||||
print "MT text A \n";
|
||||
print "MT fname $filename\n";
|
||||
print "MT newline\n";
|
||||
@@ -886,7 +886,7 @@ sub req_update
|
||||
|
||||
}
|
||||
else {
|
||||
$log->info("Updating '$filename' $wrev");
|
||||
$log->info("Updating '$filename' to ".$meta->{revision});
|
||||
print "MT +updated\n";
|
||||
print "MT text U \n";
|
||||
print "MT fname $filename\n";
|
||||
|
||||
@@ -85,6 +85,12 @@ case "$#" in
|
||||
set x $origin ; shift ;;
|
||||
esac
|
||||
|
||||
if test -z "$exec"
|
||||
then
|
||||
# No command line override and we have configuration for the remote.
|
||||
exec="--upload-pack=$(get_uploadpack $1)"
|
||||
fi
|
||||
|
||||
remote_nick="$1"
|
||||
remote=$(get_remote_url "$@")
|
||||
refs=
|
||||
|
||||
@@ -81,7 +81,14 @@ get_remote_default_refs_for_push () {
|
||||
# is to help prevent randomly "globbed" ref from being chosen as
|
||||
# a merge candidate
|
||||
expand_refs_wildcard () {
|
||||
remote="$1"
|
||||
shift
|
||||
first_one=yes
|
||||
if test "$#" = 0
|
||||
then
|
||||
echo empty
|
||||
echo >&2 "Nothing specified for fetching with remote.$remote.fetch"
|
||||
fi
|
||||
for ref
|
||||
do
|
||||
lref=${ref#'+'}
|
||||
@@ -132,7 +139,7 @@ canon_refs_list_for_fetch () {
|
||||
if test "$1" = "-d"
|
||||
then
|
||||
shift ; remote="$1" ; shift
|
||||
set $(expand_refs_wildcard "$@")
|
||||
set $(expand_refs_wildcard "$remote" "$@")
|
||||
is_explicit="$1"
|
||||
shift
|
||||
if test "$remote" = "$(get_default_remote)"
|
||||
@@ -279,3 +286,16 @@ resolve_alternates () {
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
get_uploadpack () {
|
||||
data_source=$(get_data_source "$1")
|
||||
case "$data_source" in
|
||||
config)
|
||||
uplp=$(git-repo-config --get "remote.$1.uploadpack")
|
||||
echo ${uplp:-git-upload-pack}
|
||||
;;
|
||||
*)
|
||||
echo "git-upload-pack"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
28
ident.c
28
ident.c
@@ -180,12 +180,21 @@ static const char *get_ident(const char *name, const char *email,
|
||||
email = git_default_email;
|
||||
|
||||
if (!*name) {
|
||||
if (name == git_default_name && env_hint) {
|
||||
struct passwd *pw;
|
||||
|
||||
if (0 <= error_on_no_name &&
|
||||
name == git_default_name && env_hint) {
|
||||
fprintf(stderr, env_hint, au_env, co_env);
|
||||
env_hint = NULL; /* warn only once, for "git-var -l" */
|
||||
}
|
||||
if (error_on_no_name)
|
||||
if (0 < error_on_no_name)
|
||||
die("empty ident %s <%s> not allowed", name, email);
|
||||
pw = getpwuid(getuid());
|
||||
if (!pw)
|
||||
die("You don't exist. Go away!");
|
||||
strlcpy(git_default_name, pw->pw_name,
|
||||
sizeof(git_default_name));
|
||||
name = git_default_name;
|
||||
}
|
||||
|
||||
strcpy(date, git_default_date);
|
||||
@@ -218,18 +227,3 @@ const char *git_committer_info(int error_on_no_name)
|
||||
getenv("GIT_COMMITTER_DATE"),
|
||||
error_on_no_name);
|
||||
}
|
||||
|
||||
void ignore_missing_committer_name()
|
||||
{
|
||||
/* If we did not get a name from the user's gecos entry then
|
||||
* git_default_name is empty; so instead load the username
|
||||
* into it as a 'good enough for now' approximation of who
|
||||
* this user is.
|
||||
*/
|
||||
if (!*git_default_name) {
|
||||
struct passwd *pw = getpwuid(getuid());
|
||||
if (!pw)
|
||||
die("You don't exist. Go away!");
|
||||
strlcpy(git_default_name, pw->pw_name, sizeof(git_default_name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,8 +430,6 @@ int main(int argc, char **argv)
|
||||
die("attempt to push into a shallow repository");
|
||||
|
||||
setup_ident();
|
||||
/* don't die if gecos is empty */
|
||||
ignore_missing_committer_name();
|
||||
git_config(receive_pack_config);
|
||||
|
||||
if (0 <= transfer_unpack_limit)
|
||||
|
||||
2
refs.c
2
refs.c
@@ -958,7 +958,7 @@ static int log_ref_write(struct ref_lock *lock,
|
||||
lock->log_file, strerror(errno));
|
||||
}
|
||||
|
||||
committer = git_committer_info(1);
|
||||
committer = git_committer_info(-1);
|
||||
if (msg) {
|
||||
maxlen = strlen(committer) + strlen(msg) + 2*40 + 5;
|
||||
logrec = xmalloc(maxlen);
|
||||
|
||||
@@ -96,4 +96,13 @@ test_expect_success \
|
||||
git-branch -d n/o/p &&
|
||||
git-branch n'
|
||||
|
||||
test_expect_success 'pack, prune and repack' '
|
||||
git-tag foo &&
|
||||
git-pack-refs --all --prune &&
|
||||
git-show-ref >all-of-them &&
|
||||
git-pack-refs &&
|
||||
git-show-ref >again &&
|
||||
diff all-of-them again
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
Reference in New Issue
Block a user