mirror of
https://github.com/git/git.git
synced 2024-11-15 21:53:44 +01:00
110 lines
5.1 KiB
Text
110 lines
5.1 KiB
Text
|
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
|
||
|
|