Git development
 help / color / mirror / Atom feed
* Re: [PATCH] Do _not_ call unlink on a directory
From: Matthieu Moy @ 2007-07-16 17:18 UTC (permalink / raw)
  To: Thomas Glanzmann; +Cc: git, gitster
In-Reply-To: <11846059721204-git-send-email-sithglan@stud.uni-erlangen.de>

Thomas Glanzmann <sithglan@stud.uni-erlangen.de> writes:

I believe you still have a race condition if ...

> -				if (len > state->base_dir_len && state->force && !unlink(buf) && !mkdir(buf, 0777))
> -					continue;

... buf exists here as a file ...

>  				if (!stat(buf, &st) && S_ISDIR(st.st_mode))
>  					continue; /* ok */

... and became a directory here.

> +				if (len > state->base_dir_len && state->force && !unlink(buf) && !mkdir(buf, 0777))
> +					continue;

But that's quite unlikely to happen. And I have no fix to propose.

-- 
Matthieu

^ permalink raw reply

* Re: "git clone" executed as root on solaris 10 shreds UFS (it is possible to create hardlinks for directories as root under solaris)
From: Thomas Glanzmann @ 2007-07-16 17:17 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: GIT
In-Reply-To: <alpine.LFD.0.999.0707161001300.20061@woody.linux-foundation.org>

Hello Linus,

> I'd suggest making a bug-report. ENOTEMPTY is not an optional error.
> Posix says "Shall fail".  The "unlink directories" is so old-fashioned
> that it's not even funny. The whole reason "rmdir()" was created was
> to *not* have that behaviour in the OS. 

I asked the UFS maintainer to reconsider to fix this.

        Thomas

^ permalink raw reply

* [PATCH] Do _not_ call unlink on a directory
From: Thomas Glanzmann @ 2007-07-16 17:12 UTC (permalink / raw)
  To: git, gitster; +Cc: Thomas Glanzmann

Calling unlink on a directory on a Solaris UFS filesystem as root makes it
inconsistent. Thanks to Johannes Sixt for the obvious fix.
---
 entry.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/entry.c b/entry.c
index 82bf725..1f2e34d 100644
--- a/entry.c
+++ b/entry.c
@@ -14,10 +14,10 @@ static void create_directories(const char *path, const struct checkout *state)
 		if (mkdir(buf, 0777)) {
 			if (errno == EEXIST) {
 				struct stat st;
-				if (len > state->base_dir_len && state->force && !unlink(buf) && !mkdir(buf, 0777))
-					continue;
 				if (!stat(buf, &st) && S_ISDIR(st.st_mode))
 					continue; /* ok */
+				if (len > state->base_dir_len && state->force && !unlink(buf) && !mkdir(buf, 0777))
+					continue;
 			}
 			die("cannot create directory at %s", buf);
 		}
-- 
1.5.2.1

^ permalink raw reply related

* Re: "git clone" executed as root on solaris 10 shreds UFS (it ispossible to create hardlinks for directories as root under solaris)
From: Thomas Glanzmann @ 2007-07-16 17:12 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: git, Linus Torvalds, Junio C Hamano
In-Reply-To: <469B821E.85E5EDA9@eudaptics.com>

Hello Johannes,

> Try swapping the two inner-most if-blocks.

I did and it works as expected:

        (faui04a) [/var/tmp] git clone ~sithglan/work/repositories/public/easix.git test-8
        Initialized empty Git repository in /var/tmp/test-8/.git/
        remote: Generating pack...
        remote: Done counting 317 objects.
        remote: Deltifying 317 objects...
        remote:  100% (317/317remote: ) done
        Indexing 317 objects...
        remote: Total 317 (delta 182), reused 278 (delta 157)
        100% (317/317) done
        Resolving 182 deltas...
        100% (182/182) done

        (faui04a) [/var/tmp] cd test-8
        ./test-8
        (faui04a) [/var/tmp/test-8] git status
        # On branch master
        nothing to commit (working directory clean)
        (faui04a) [/var/tmp/test-8] cd ..
        (faui04a) [/var/tmp] rm -rf test-8

... I have a filesystem to check. :-)

        Thomas

^ permalink raw reply

* Re: "git clone" executed as root on solaris 10 shreds UFS (it is possible to create hardlinks for directories as root under solaris)
From: Linus Torvalds @ 2007-07-16 17:07 UTC (permalink / raw)
  To: Thomas Glanzmann; +Cc: GIT, Junio C Hamano
In-Reply-To: <alpine.LFD.0.999.0707161001300.20061@woody.linux-foundation.org>



On Mon, 16 Jul 2007, Linus Torvalds wrote:
>
> Solaris is apparently a buggy piece of crap.
> 
> I'd suggest making a bug-report. ENOTEMPTY is not an optional error. Posix 
> says "Shall fail".

Oh, it was apparetly "unlink()" that corrupts filesystems. Which isn't 
against Posix, it's just stupid.

The "unlink directories" is so old-fashioned that it's not even funny. The 
whole reason "rmdir()" was created was to *not* have that behaviour in the 
OS. 

So I'll have to correct my statement. Please remove the "buggy" from 
"buggy piece of crap". The rest stands.

		Linus

^ permalink raw reply

* Re: "git clone" executed as root on solaris 10 shreds UFS (it is possible to create hardlinks for directories as root under solaris)
From: Linus Torvalds @ 2007-07-16 17:03 UTC (permalink / raw)
  To: Thomas Glanzmann; +Cc: GIT, Junio C Hamano
In-Reply-To: <20070716133602.GB26675@cip.informatik.uni-erlangen.de>



On Mon, 16 Jul 2007, Thomas Glanzmann wrote:
>
> I think it is. Damn it. What seems to hapen here is that git does:
> 
>         - create a subdirectory
>         - puts a file in
>         - deletes a subdirectory (by call unlink - that would normally fail,
>           but with solaris as root it does not fail)

Solaris is apparently a buggy piece of crap.

I'd suggest making a bug-report. ENOTEMPTY is not an optional error. Posix 
says "Shall fail".

			Linus

^ permalink raw reply

* Re: "git clone" executed as root on solaris 10 shreds UFS (it is possible to create hardlinks for directories as root under solaris)
From: Thomas Glanzmann @ 2007-07-16 16:40 UTC (permalink / raw)
  To: GIT
In-Reply-To: <20070716131537.GA26675@cip.informatik.uni-erlangen.de>

Hello,


> exactly. The question is: Is it a Solaris bug or is it something that is
> supposed a user is able to do (it doesn't make sense for me)? I posted
> this problem to comp.unix.solaris and also contacted the UFS Maintainer
> of Solaris (it is not the first UFS bug I original found). If I don't
> receive feedback, I am going to open a call with Sun. Whatever is going
> on (hopefully it isn't PEBKAC - but I don't think so) and this time it
> isn't broken hardware either (like the last time I reported a serious
> git bug) because it happens on two machines.

below I quote the answer of the UFS maintainer:

Thomas,

some notes on the unlink(directory) part:

In the case of calling unlink(2) on a directory as a privilidged user, things
like ".." (and the link count in the parent) would not be cleaned up.

The man page for unlink(1M) and unlink(2) is very clear about using rmdir(1/2) to
remove a directory.  It's also very clear that this does exactly what
it's supposed to do: Remove a link to a file/directory.  Cleaning up
the ".." entry (which would clean up the link to the parent) could
be considered "extra".

First the standards issues:
    The link(BA_OS) and unlink(BA_OS) descriptions in SVID3 both specify that
    a process with appropriate privileges is allowed to operate on a directory.
    We have claimed to conform to SVID3 since Solaris 2.0 and have not announced
    that we ever plan to EOL SVID3 conformance.

    UFS does support link(2)/unlink(2) with appropriate privilidges of
    directories while ZFS does not.

    The change that would provide ``Cleaning up the ".." entry ...'' would
    violate both SVID3 and POSIX and SUS requirements.  (The unlink(path)
    system call is supposed to remove the directory entry named by path; not
    the directory entry named by path and an arbitrary number of other
    directory entries.)

Second some history:
    Back before there were mkdir() and rmdir() system calls, applications
    wanting to create a directory invoked the setuid root mkdir utility
    which performed a series of mknod() and link() operations to create the
    directory and create dot and dot-dot entries in the new directory.
    Similarly, applications wanting to remove a directory invoked the
    setuid root rmdir uility which performed a series of unlink()
    operations to destroy the directory if it was empty.

    Not quite so far back in ancient history, there is also the point
    that before symlinks were available it was common practice to make
    hard links to directories.  Privileged applications can still do this
    today (as mandated by SVID) using the link() and unlink() system calls
    and the link and unlink commands.

UFS and ZFS are actually both correct, the standards wording permits either way kind of:

<snip>
If path1 names a directory, link() shall fail unless the process has
appropriate privileges and the implementation supports using link() on directories.

The path argument shall not name a directory unless the process has
appropriate privileges and the implementation supports using unlink() on directories.
<snip end>

This seems to implicitely allow an escape route; we can declare that no process
has sufficient privileges to link(2)/unlink(2) directories or like ZFS did,
have the underlaying implementation not supporting it at all.

The proper way is for the application to use the rmdir(2) system call,
it's there since ages!

my bottom line: GIT should not call unlink on a directory.

        Thomas

^ permalink raw reply

* Re: Can someone explain this git-blame/git-rev behavior to me?
From: David Kastrup @ 2007-07-16 16:38 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 125 bytes --]


Oops, I accidentally sent the following mail in private.  So I have to
forward back to the list (don't have the original):


[-- Attachment #2: Type: message/rfc822, Size: 2671 bytes --]

From: Johannes Sixt <J.Sixt@eudaptics.com>
To: David Kastrup <dak@gnu.org>
Subject: Re: Can someone explain this git-blame/git-rev behavior to me?
Date: Mon, 16 Jul 2007 18:09:39 +0200
Message-ID: <469B9843.835B5356@eudaptics.com>

David Kastrup wrote:
> 
> Johannes Sixt <J.Sixt@eudaptics.com> writes:
> 
> > David Kastrup wrote:
> 
> >> [nonsense not really related to the problem he has been seeing]
> 
> > [Johannes replied with a reasonable analysis]
> 
> Ok, scratch that.  I got completely confused.  Here is the gist of the
> problem that kicked me, this time boiled down to the actually relevant
> part:
> 
> I am looking for a descendant of tags/v1.4.4-rc1~72 with regard to
> contrib/emacs/vc-git.el by scanning the output of the first command
> in the following pipeline:
> 
> git-rev-list --parents HEAD ^tags/v1.4.4-rc1~72 -- vc-git.el|git-name-rev --stdin|fgrep tags/v1.4.4-rc1
> 
> This gives:
> 4de0f9f9b6ed1731de00b67952504e5a783f54a4 (tags/v1.5.0-rc0~31) 1259404c7e5cd88b7f6692986469cd20cbfacdad (tags/v1.4.4-rc1~71)
> 1259404c7e5cd88b7f6692986469cd20cbfacdad (tags/v1.4.4-rc1~71) b4aee09e610567529dc619d7324dc2fe85a11db5 (tags/v1.4.4-rc1~72) 0abc0260fa3419de649fcc1444e3d256a17ca6c7 (tags/v1.4.3.2~6)
> 
> And this looks like it would tell us that tags/v1.4.4-rc1~72 has with
> regard to vc-git.el a child tags/v1.4.4-rc1~71 and a grandchild of
> tags/v1.5.0-rc0~31.
> 
> Now if I instead do
> git-rev-list --parents HEAD -- vc-git.el|git-name-rev --stdin|fgrep tags/v1.4.4-rc1
> 
> 4de0f9f9b6ed1731de00b67952504e5a783f54a4 (tags/v1.5.0-rc0~31) b4aee09e610567529dc619d7324dc2fe85a11db5 (tags/v1.4.4-rc1~72)
> b4aee09e610567529dc619d7324dc2fe85a11db5 (tags/v1.4.4-rc1~72) 474a90fef9ebcdedee041b2def4b9a98b94cd146 (tags/v1.4.3.2~8)
> 
> I get to see that the child of tags/v1.4.4-rc1~72 is actually
> tags/v1.5.0-rc0~31, skipping tags/v1.4.4-rc1~71 which presumably did
> not change vc-git.el.
> 
> So the ^tags/v1.4.4-rc1~72 specification caused an additional mention
> of tags/v1.4.4-rc1~71 even though, with regard to vc-git.el, it would
> be equivalent to tags/v1.4.4-rc1~72.
> 
> So is there a way I can get the information of the second call without
> the performance loss of going through the entire history?

You better send the question again, this time to the list. I'm certainly
not the one who can answer this or even solve it.

It seems that there is an unwanted interaction between --parents and
history simplification at the edge commits. I don't think that there
will be an easy solution.

-- Hannes


[-- Attachment #3: Type: text/plain, Size: 66 bytes --]



So anybody has an idea how to go about this?

-- 
David Kastrup

^ permalink raw reply

* Re: [WIP PATCH 6/6] notes: add notes-index for a substantial speedup.
From: Johannes Schindelin @ 2007-07-16 16:29 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: Alberto Bertogli, git, gitster, Johan Herland
In-Reply-To: <20070716060117.GF32566@spearce.org>

Hi,

On Mon, 16 Jul 2007, Shawn O. Pearce wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> > 
> > Actually, this commit adds two methods for a notes index:
> > 
> > - a sorted list with a fan out to help binary search, and
> > - a modified hash table.
> > 
> > It also adds a test which is used to determine the best algorithm.
> 
> I know this is a nice backwards compatible way to organize notes,
> and to make them reasonably efficiently found, but I'd almost
> rather just see them crammed into the packfile alongside of the
> commit it annotates, so that the packfile reader can quickly find
> the annotation at the same time it finds the commit.
> 
> aka packv4.
> 
> Ok, enough dreaming for today.

Yes, I also dream of having the time to play with packv4.  If you read my 
comments in the commit-annotation thread, you'll see that I stated that 
packv4 would solve the problem, too.

The reason I did this series was not to push commit notes, but to make 
good for stalling Johan's efforts.  Including a proof that the commit 
notes as I introduced them can be relatively cheap, too.

Ciao,
Dscho

^ permalink raw reply

* Re: "git clone" executed as root on solaris 10 shreds UFS (it is possible to create hardlinks for directories as root under solaris)
From: David Kastrup @ 2007-07-16 16:29 UTC (permalink / raw)
  To: git
In-Reply-To: <20070716133602.GB26675@cip.informatik.uni-erlangen.de>

Thomas Glanzmann <thomas@glanzmann.de> writes:

> Hello,
> might that be related to the problem:
>
>
>         lstat64("profiles/icpc", 0xFFBFF350)            Err#2 ENOENT
> =>       mkdir("profiles", 0777)                         = 0
>         stat64(".git/objects/66/6197b02f46c92f0273f16ac77d34d76b28f4f0",
>         0xFFBFF088) = 0
>         open64(".git/objects/66/6197b02f46c92f0273f16ac77d34d76b28f4f0",
>         O_RDONLY) = 4
>         mmap64(0x00000000, 284, PROT_READ, MAP_PRIVATE, 4, 0) = 0xFF230000
>         close(4)                                        = 0
>         munmap(0xFF230000, 284)                         = 0
>         open64("profiles/icpc", O_WRONLY|O_CREAT|O_EXCL, 0666) = 4
>         open64("profiles/.gitattributes", O_RDONLY)     Err#2 ENOENT
>         write(4, " #   I C P C   P r o f i".., 420)     = 420
>         close(4)                                        = 0
>         lstat64("profiles/sithglan", 0xFFBFF350)        Err#2 ENOENT
> =>      mkdir("profiles", 0777)                         Err#17 EEXIST
> =>      unlink("profiles")                              = 0
> =>      mkdir("profiles", 0777)                         = 0
>
> I think it is. Damn it. What seems to hapen here is that git does:
>
>         - create a subdirectory
>         - puts a file in
>         - deletes a subdirectory (by call unlink - that would normally fail,
>           but with solaris as root it does not fail)
>
>                 => here comes the dangling hard link counter
>
>         - created the directory again
>         - puts the file in
>
> That is why I only see one file in each subdirectory (the one that got
> checkedout last). So the fix for git should be straight forward. But I still
> think that Solaris is obviously broken. Because if you ask me it should not be
> possible to unlink a directory that has files in it?!

<URL:http://www.opengroup.org/onlinepubs/000095399/functions/unlink.html>

    The path argument shall not name a directory unless the process has
    appropriate privileges and the implementation supports using unlink()
    on directories.

So Solaris has the right to do this.

    APPLICATION USAGE

        Applications should use rmdir() to remove a directory.

    RATIONALE

        Unlinking a directory is restricted to the superuser in many
        historical implementations for reasons given in link() (see
        also rename()).


In short: git should not call remove, ever.  It may succeed, and is a
badly low-level call.  If something is known to be a directory, then
it needs to be removed using rmdir, and if it is a nondirectory, with
unlink.

Hm, browsing through Posix indicates that unlink is probably the same
as remove.  Pity.  I thought that just "remove" was the potential
evildoer.

-- 
David Kastrup

^ permalink raw reply

* Re: [PATCH 0/6] Introduce commit notes
From: Johannes Schindelin @ 2007-07-16 16:26 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Andy Parkins, git, Alberto Bertogli, Johan Herland
In-Reply-To: <7vbqec4vk2.fsf@assigned-by-dhcp.cox.net>

Hi,

On Mon, 16 Jul 2007, Junio C Hamano wrote:

> Andy Parkins <andyparkins@gmail.com> writes:
> 
> > On Monday 2007 July 16, Johannes Schindelin wrote:
> >
> >> The biggest obstacle was a thinko about the scalability.  Tree 
> >> objects take free form name entries, and therefore a binary search by 
> >> name is not possible.
> >
> > I might be misunderstanding, but in the case of the notes tree objects 
> > isn't it true that the name entries aren't free form, but are 
> > guaranteed to be of a fixed length form:
> >
> >   XX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
> >
> > In which case you can binary search?
> 
> Hmph, you are right.  In this sequence:
> 
> 	hex = sha1_to_hex(commit->object.sha1);
> 	snprintf(name, sizeof(name), "%s:%.*s/%.*s",
> 			notes_ref_name, 2, hex, 38, hex + 2);
> 	if (get_sha1(name, sha1))
> 		return;
> 
> Instead, we could read the tree object by hand in the commit that is 
> referenced by notes_ref_name, which has uniform two letter names for 
> subtrees which can be binary searched, open the tree for that entry, 
> again by hand, and do another binary search because that tree has 
> uniform 38-letter names.  That certainly could be done.
> 
> Sounds like a "fun" project for some definition of the word.

I disagree.  One disadvantage to using tree objects is that it is much 
easier to have pilot errors.  You could even make a new working tree 
checking out refs/notes/commits and change/add/remove files.

Ciao,
Dscho

^ permalink raw reply

* I never want to push a given change
From: nathan bullock @ 2007-07-16 16:18 UTC (permalink / raw)
  To: git

I have been using git for a little while and one thing that I would like to
be able to do is never push a given change, or set of changes.

So lets say I clone a .git repository. Then I make a couple of changes
that I don't want anyone else to see, do a commit. Then I make some
other changes that I want everyone else to see and do another commit.

How do I push just the second commit?
And how do I make it so that every other time I do a push after this that
first commit will never be sent?

Thanks,
Nathan

ps. I am really enjoying using git. Thanks.

^ permalink raw reply

* Changes in function read_pipe
From: Carlos Rica @ 2007-07-16 16:13 UTC (permalink / raw)
  To: git, Kristian Høgsberg, Johannes Schindelin

Some people talked recently about renaming the function read_pipe
(sha1_file.c) to the better name read_fd.
Here I discuss other possible changes to the current version:

1. It now requires to allocate memory for the buffer before calling it,
you cannot pass it a pointer set to NULL or not initializated at all.

2. The function doesn't terminate the data with NUL, and if you
need that, you must to realloc before adding the '\0', because
the function only returns the size of the data, not the buffer size.

3. When function fails in reading (xread returns < 0), buffer is not
freed.

I'm not sure which of those issues are really important,
so I thought it was better to ask this in the list.
This is the current implementation of the function:

/*
 * reads from fd as long as possible into a supplied buffer of size bytes.
 * If necessary the buffer's size is increased using realloc()
 *
 * returns 0 if anything went fine and -1 otherwise
 *
 * NOTE: both buf and size may change, but even when -1 is returned
 * you still have to free() it yourself.
 */
int read_pipe(int fd, char** return_buf, unsigned long* return_size)
{
	char* buf = *return_buf;
	unsigned long size = *return_size;
	ssize_t iret;
	unsigned long off = 0;

	do {
		iret = xread(fd, buf + off, size - off);
		if (iret > 0) {
			off += iret;
			if (off == size) {
				size *= 2;
				buf = xrealloc(buf, size);
			}
		}
	} while (iret > 0);

	*return_buf = buf;
	*return_size = off;

	if (iret < 0)
		return -1;
	return 0;
}

Kristian Høgsberg recently sent some changes to the function
to replace the function with another one easier to call, but
with a different behavior:

 /*
- * reads from fd as long as possible into a supplied buffer of size bytes.
- * If necessary the buffer's size is increased using realloc()
+ * reads from fd as long as possible and allocates a buffer to hold
+ * the contents.  The buffer and size of the contents is returned in
+ * *return_buf and *return_size.  In case of failure, the allocated
+ * buffers are freed, otherwise, the buffer must be freed using xfree.
  *
  * returns 0 if anything went fine and -1 otherwise
- *
- * NOTE: both buf and size may change, but even when -1 is returned
- * you still have to free() it yourself.
  */
-int read_pipe(int fd, char** return_buf, unsigned long* return_size)
+int read_fd(int fd, char** return_buf, unsigned long* return_size)
 {
-	char* buf = *return_buf;
-	unsigned long size = *return_size;
+	unsigned long size = 4096;
+	char* buf = xmalloc(size);
 	ssize_t iret;
 	unsigned long off = 0;

@@ -2328,21 +2327,22 @@ int read_pipe(int fd, char** return_buf, unsigned long* return_size)
 	*return_buf = buf;
 	*return_size = off;

-	if (iret < 0)
+	if (iret < 0) {
+		free(buf);
 		return -1;
+	}
+
 	return 0;
 }

Any other ideas? read_pipe is really handy to reuse on builtins,
so we need to decide how we should call to it now before starting
to reuse it in many places.

Comments will be appreciated.

^ permalink raw reply

* Re: "git clone" executed as root on solaris 10 shreds UFS (it ispossible to create hardlinks for directories as root under solaris)
From: Brian Downing @ 2007-07-16 15:50 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: git, Linus Torvalds, Junio C Hamano
In-Reply-To: <20070716154559.GD19073@lavos.net>

On Mon, Jul 16, 2007 at 10:45:59AM -0500, Brian Downing wrote:
> http://www.opengroup.org/onlinepubs/007908799/xsh/unlink.html
> 
> | The path argument must not name a directory unless the process has
> | appropriate privileges and the implementation supports using unlink() on
> | directories.
> 
> The above seems to imply that implementations are free to do something
> with directories passed to unlink, and that it is the responsibility
> if the user not to do that unless they know what is going to happen.

Also, the HISTORY section of the FreeBSD manpages states:

| The unlink system call traditionally allows the super-user to unlink
| directories which can damage the filesystem integrity. This
| implementation no longer permits it.

Great.

-bcd

^ permalink raw reply

* Re: "git clone" executed as root on solaris 10 shreds UFS (it ispossible to create hardlinks for directories as root under solaris)
From: Brian Downing @ 2007-07-16 15:45 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: git, Linus Torvalds, Junio C Hamano
In-Reply-To: <469B821E.85E5EDA9@eudaptics.com>

On Mon, Jul 16, 2007 at 04:35:10PM +0200, Johannes Sixt wrote:
> It tries to remove a *file* that is in the way and create the directory
> in its place. But since your unlink() behaves incorrectly (it is
> supposed to *fail* for directories), the logic does not quite work as
> expected - it mistakes the directory for a file.

http://www.opengroup.org/onlinepubs/007908799/xsh/unlink.html

| The path argument must not name a directory unless the process has
| appropriate privileges and the implementation supports using unlink() on
| directories.

The above seems to imply that implementations are free to do something
with directories passed to unlink, and that it is the responsibility
if the user not to do that unless they know what is going to happen.

-bcd

^ permalink raw reply

* Re: "git clone" executed as root on solaris 10 shreds UFS (it ispossible  to create hardlinks for directories as root under solaris)
From: Johannes Sixt @ 2007-07-16 14:35 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <20070716134529.GC26675@cip.informatik.uni-erlangen.de>

Thomas Glanzmann wrote:
>         static void create_directories(const char *path, const struct checkout *state)
>         {
>         ...
>                         if (mkdir(buf, 0777)) {
> =>                              if (errno == EEXIST) {
>                                         struct stat st;
> =>                                      if (len > state->base_dir_len && state->force && !unlink(buf) && !mkdir(buf, 0777))
>                                                 continue;
>                                         if (!stat(buf, &st) && S_ISDIR(st.st_mode))
>                                                 continue; /* ok */
>                                 }
>                                 die("cannot create directory at %s", buf);
>                         }
>         ...
> 
> I think here is the problem. I don't understand what the code should do
> actually. Or why the directory is deleted and re-created (maybe something todo
> with permissions)?

It tries to remove a *file* that is in the way and create the directory
in its place. But since your unlink() behaves incorrectly (it is
supposed to *fail* for directories), the logic does not quite work as
expected - it mistakes the directory for a file.

Try swapping the two inner-most if-blocks.

-- Hannes

^ permalink raw reply

* Re: "git clone" executed as root on solaris 10 shreds UFS (it is possible to create hardlinks for directories as root under solaris)
From: Thomas Glanzmann @ 2007-07-16 13:45 UTC (permalink / raw)
  To: GIT; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <20070716100803.GA24036@cip.informatik.uni-erlangen.de>

Hello,

entry.c line 17:

        static void create_directories(const char *path, const struct checkout *state)
        {
        ...
                        if (mkdir(buf, 0777)) {
=>                              if (errno == EEXIST) {
                                        struct stat st;
=>                                      if (len > state->base_dir_len && state->force && !unlink(buf) && !mkdir(buf, 0777))
                                                continue;
                                        if (!stat(buf, &st) && S_ISDIR(st.st_mode))
                                                continue; /* ok */
                                }
                                die("cannot create directory at %s", buf);
                        }
        ...

I think here is the problem. I don't understand what the code should do
actually. Or why the directory is deleted and re-created (maybe something todo
with permissions)?

        Thomas

^ permalink raw reply

* Re: "git clone" executed as root on solaris 10 shreds UFS (it is possible to create hardlinks for directories as root under solaris)
From: Thomas Glanzmann @ 2007-07-16 13:36 UTC (permalink / raw)
  To: GIT; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <20070716100803.GA24036@cip.informatik.uni-erlangen.de>

Hello,
might that be related to the problem:


        lstat64("profiles/icpc", 0xFFBFF350)            Err#2 ENOENT
=>       mkdir("profiles", 0777)                         = 0
        stat64(".git/objects/66/6197b02f46c92f0273f16ac77d34d76b28f4f0",
        0xFFBFF088) = 0
        open64(".git/objects/66/6197b02f46c92f0273f16ac77d34d76b28f4f0",
        O_RDONLY) = 4
        mmap64(0x00000000, 284, PROT_READ, MAP_PRIVATE, 4, 0) = 0xFF230000
        close(4)                                        = 0
        munmap(0xFF230000, 284)                         = 0
        open64("profiles/icpc", O_WRONLY|O_CREAT|O_EXCL, 0666) = 4
        open64("profiles/.gitattributes", O_RDONLY)     Err#2 ENOENT
        write(4, " #   I C P C   P r o f i".., 420)     = 420
        close(4)                                        = 0
        lstat64("profiles/sithglan", 0xFFBFF350)        Err#2 ENOENT
=>      mkdir("profiles", 0777)                         Err#17 EEXIST
=>      unlink("profiles")                              = 0
=>      mkdir("profiles", 0777)                         = 0

I think it is. Damn it. What seems to hapen here is that git does:

        - create a subdirectory
        - puts a file in
        - deletes a subdirectory (by call unlink - that would normally fail,
          but with solaris as root it does not fail)

                => here comes the dangling hard link counter

        - created the directory again
        - puts the file in

That is why I only see one file in each subdirectory (the one that got
checkedout last). So the fix for git should be straight forward. But I still
think that Solaris is obviously broken. Because if you ask me it should not be
possible to unlink a directory that has files in it?!

                Thomas

^ permalink raw reply

* Re: Tips for debugging fast-import front-ends
From: Johannes Sixt @ 2007-07-16 13:32 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.64.0707161336570.24955@reaper.quantumfyre.co.uk>

Julian Phillips wrote:
> At some point in the "messy" phase I get an error from fast-import saying:
> 
> fatal: path foo not in branch
> 
> This seems to happen when I attempt to copy a file that is also changed in
> the same commit.  What I would like to do is find out what things look
> like just before that point - the problem is that fast-import seems to not
> create anything on failure.  So, apart restarting the import and stopping
> just before the broken commit, is there any way to find out what
> fast-import thinks the branch looks like?

Redirect the input stream to a file instead of to fast-import, then feed
fast-import from this file. This way you can reproduce the failure more
quickly. Also, you can run fast-import from a debugger.

-- Hannes

^ permalink raw reply

* Re: git-config: replaces ~/.gitconfig symlink with real file
From: Bradford Smith @ 2007-07-16 13:26 UTC (permalink / raw)
  To: Nikolai Weibull; +Cc: git
In-Reply-To: <f158199e0707160433v27fe7073w9c550712c41c32e8@mail.gmail.com>

On 7/16/07, Bradford Smith <bradford.carl.smith@gmail.com> wrote:
> On 7/16/07, Nikolai Weibull <now@bitwi.se> wrote:
> > On 7/15/07, Bradford Smith <bradford.carl.smith@gmail.com> wrote:
> > > Since the number of dot-files and dot-directories that I have in my
> > > home directory these days is somewhat overwhelming, I like to keep
> > > those I directly edit all together in an ~/etc directory so I can
> > > easily back them up and/or copy them in bulk to new accounts.  So,
> > > several of my home dot-files are just symlinks to something in ~/etc,
> > > including ~/.gitconfig.
> >
> > How about adding an environment variable telling Git where to find
> > user-global .gitconfig instead?
> > > home directory these days is somewhat overwhelming, I like to keep
> > > those I directly edit all together in an ~/etc directory so I can
> > > easily back them up and/or copy them in bulk to new accounts.  So,
> > > several of my home dot-files are just symlinks to something in ~/etc,
> > > including ~/.gitconfig.
> >
> > How about adding an environment variable telling Git where to find
> > user-global .gitconfig instead?
>
> Thanks for suggesting that.
>
> Actually, by looking at the code I discovered I could use the
> environment variable GIT_CONFIG to specify where the configuration
> file is, and I have already changed my setup to use this.
> Unfortunately, I found the documentation for this variable in
> git-config(1) confusing or I would have used it before.  If I get the
> chance, I'll submit a patch for git-config.txt, and maybe for git.txt
> as well, since it lists lots of other environment variables but not
> GIT_CONFIG or GIT_CONFIG_LOCAL.
>
> Thanks,
>
> Bradford
>

Drat!  The documentation wasn't as wrong as I had hoped.  If I set
GIT_CONFIG, git will ignore $(prefix)/etc/gitconfig and ~/.git/config,
which isn't what I want.  So, I guess I need to add a GIT_CONFIG_HOME
environment variable.  If I get that done, I'll send a patch to the
list including doc updates.

Of course, if someone else wants to do it first, I won't complain. B')

Thanks,

Bradford

^ permalink raw reply

* Re: Can someone explain this git-blame/git-rev behavior to me?
From: Johannes Sixt @ 2007-07-16 13:24 UTC (permalink / raw)
  To: git
In-Reply-To: <86sl7oaasx.fsf@lola.quinscape.zz>

David Kastrup wrote:
> git-name-rev b5dd9d20
> b5dd9d20 tags/v1.4.2-rc1~88
> 
> So what is it I am doing wrong here?  The problem I have is that in
> Emacs, one can go to the "next version" in an annotated file, and I
> get stuck in a loop here, since tags/v1.4.2-rc1~88 delivers
> 
> git-rev-list HEAD --not tags/v1.4.2-rc1~88 --parents contrib/emacs/vc-git.el|tail -1|git-name-rev --stdin
> 
> d87b90e47f7430455385edcf8506288b9a73d3b5 (tags/v1.4.2-rc1~87) b5dd9d2027c1bd5758033c7baf6d087752b0263d (tags/v1.4.2-rc1~88) 280242d1cc1fe2847f649d2f16b273e168fcbc48 (tags/v1.4.2-rc1~92)
> 
> So we have tags/v1.4.2-rc1~87 listed as successor again, so I get into
> a loop of blame.
> 
> Is there something I don't understand about merges?

rev-list --parents list both the commit and its parent(s). If you are
only interested in the parents, ignore the first SHA1 on the line.

-- Hannes

^ permalink raw reply

* Re: "git clone" executed as root on solaris 10 shreds UFS (it is possible to create hardlinks for directories as root under solaris)
From: Thomas Glanzmann @ 2007-07-16 13:15 UTC (permalink / raw)
  To: David Kastrup; +Cc: GIT
In-Reply-To: <86myxw8pzg.fsf@lola.quinscape.zz>

Hello David,

> Hm?  The hard link counter is "broken" by creating or not creating
> subdirectories, since their ".." is a hard link.

exactly. The question is: Is it a Solaris bug or is it something that is
supposed a user is able to do (it doesn't make sense for me)? I posted
this problem to comp.unix.solaris and also contacted the UFS Maintainer
of Solaris (it is not the first UFS bug I original found). If I don't
receive feedback, I am going to open a call with Sun. Whatever is going
on (hopefully it isn't PEBKAC - but I don't think so) and this time it
isn't broken hardware either (like the last time I reported a serious
git bug) because it happens on two machines.

        Thomas

^ permalink raw reply

* Re: "git clone" executed as root on solaris 10 shreds UFS (it is possible to create hardlinks for directories as root under solaris)
From: David Kastrup @ 2007-07-16 12:58 UTC (permalink / raw)
  To: git
In-Reply-To: <20070716123913.GJ24036@cip.informatik.uni-erlangen.de>

Thomas Glanzmann <thomas@glanzmann.de> writes:

> Hello David,
> as I mentioned and showed in my original e-mail:
>
>         git checkout /path/to/repo
>
> triggers the problem also. So no, "cp -a" has nothing todo with it
> because root is able to read _all_ files no matter who the files are
> owned by and what the permissions of these files are[1]. This happens on
> a _local_ fileystem. And what worries me is that git does something that
> breaks the _hard link counter_ of a directory.

Hm?  The hard link counter is "broken" by creating or not creating
subdirectories, since their ".." is a hard link.

-- 
David Kastrup

^ permalink raw reply

* Re: "git clone" executed as root on solaris 10 shreds UFS (it is possible to create hardlinks for directories as root under solaris)
From: Thomas Glanzmann @ 2007-07-16 12:46 UTC (permalink / raw)
  To: GIT; +Cc: Linus Torvalds, Junio C Hamano
In-Reply-To: <20070716100803.GA24036@cip.informatik.uni-erlangen.de>

Hello again,
it is definitively "git-checkout-index -a -f":

truss output is at http://wwwcip.informatik.uni-erlangen.de/~sithglan/git_checkout_index_a_f.truss.gz

        Thomas

^ permalink raw reply

* Tips for debugging fast-import front-ends
From: Julian Phillips @ 2007-07-16 12:45 UTC (permalink / raw)
  To: git; +Cc: Shawn O. Pearce

I was wondering if anyone had some handy tips for debugging fast-import 
based importers?

I'm trying to import an SVN repository that was initially created by 
cvs2svn and, since we started using branches quite heavily _before_ 
switching to SVN, there is some quite messy history.

At some point in the "messy" phase I get an error from fast-import saying:

fatal: path foo not in branch

This seems to happen when I attempt to copy a file that is also changed in 
the same commit.  What I would like to do is find out what things look 
like just before that point - the problem is that fast-import seems to not 
create anything on failure.  So, apart restarting the import and stopping 
just before the broken commit, is there any way to find out what 
fast-import thinks the branch looks like?

Also, does anyone have any handy hints 'n' tips for working with 
fast-import?

-- 
Julian

  ---
Air pollution is really making us pay through the nose.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox