Git development
 help / color / mirror / Atom feed
* Re: Restoring timestamps (Re: Branches & directories)
From: Jonathan Nieder @ 2011-08-22 23:21 UTC (permalink / raw)
  To: Hilco Wijbenga
  Cc: Kyle Moffett, Michael Witten, Junio C Hamano, Evan Shelhamer,
	Git Mailing List
In-Reply-To: <CAE1pOi1+nnpnHAuhYsXcfFNUroW0JcDQKLu6D7YNrUwJg0tXPw@mail.gmail.com>

Hilco Wijbenga wrote:

> You mean an extra dotfile per file in the commit?

Let me step back a moment.

When you mentioned mtime, a switch went off and reminded me of the
problem of metadata in general, especially owner and permissions. That
problem is important for people keeping track of /etc or $HOME in
version control (always a little dangerous because of the effect of a
stray "git reset --hard", but never mind). And the last time it came
up, I convinced myself that a hook script setting up entries in
.gitattributes, .gitmetadata, or .etckeepr with information like "all
files are owned by root:root unless otherwise specified" could be a
good and not too invasive way to deal with that.

Now that you remind me that the mtime of every file is likely to
differ from every other file, it is harder to imagine what situation
would make this meaningful information that should be stored in the
repository and shared with other people. It seems more like something
associated to the worktree, which fits more closely with what you are
trying to do, anyway.

Regarding the problem "eclipse metadata is not carried over from one
worktree to another", isn't that going to be a problem regardless? In
your proposed setup, each time you stash everything and start work on
a different branch, the eclipse metadata before would be stashed along
with everything else, which doesn't make anything any easier (unless
disk space is very scarce or metadata stores the absolute path to the
cwd).

Sorry for the lack of clarity.
Jonathan

^ permalink raw reply

* [PATCH] gitweb: highlight: strip non-printable characters via col(1)
From: Christopher M. Fuhrman @ 2011-08-22 22:58 UTC (permalink / raw)
  To: gitster, git; +Cc: jnareb, cwilson, sylvain, Christopher M. Fuhrman

From: "Christopher M. Fuhrman" <cfuhrman@panix.com>

The current code, as is, passes control characters, such as form-feed
(^L) to highlight which then passes it through to the browser.  This
will cause the browser to display one of the following warnings:

Safari v5.1 (6534.50) & Google Chrome v13.0.782.112:

  This page contains the following errors:

  error on line 657 at column 38: PCDATA invalid Char value 12
  Below is a rendering of the page up to the first error.

Mozilla Firefox 3.6.19 & Mozilla Firefox 5.0:

   XML Parsing Error: not well-formed
   Location:
   http://path/to/git/repo/blah/blah

Both errors were generated by gitweb.perl v1.7.3.4 w/ highlight 2.7
using arch/ia64/kernel/unwind.c from the Linux kernel.

Strip non-printable control-characters by piping the output produced
by git-cat-file(1) to col(1) as follows:

  git cat-file blob deadbeef314159 | col -bx | highlight <args>

Note usage of the '-x' option which tells col(1) to output multiple
spaces instead of tabs.

Tested under OpenSuSE 11.4 & NetBSD 5.1 using perl 5.12.3 and perl
5.12.2 respectively using Safari, Firefox, and Google Chrome.

Signed-off-by: Christopher M. Fuhrman <cfuhrman@panix.com>
---
Howdy,

I haven't gotten any responses to my patch for a while, so I am now
submitting this for general inclusion into git.  Please note that this
is based off the "maint" branch per Documentation/SubmittingPatches

For an example of this bug in action, see:

* http://git.fuhrbear.com/~cfuhrman/?p=linux/.git;a=blob;f=arch/alpha/kernel/core_titan.c;h=219bf271c0ba2e5f2d668af707df57fbbd00ccfd;hb=HEAD
* http://git.fuhrbear.com/~cfuhrman/?p=linux/.git;a=blob;f=arch/ia64/kernel/unwind.c;h=fed6afa2e8a9014e65229e51e64fa4b1c13cc284;hb=HEAD

WRT the col(1) command, I've verified that the binary is installed in
/usr/bin on OpenSuSE, NetBSD, OpenBSD, Solaris 10, and AIX.  This
patch assumes that /usr/bin is in $PATH.

Cheers!

 gitweb/gitweb.perl |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 50a835a..4c68165 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -3656,6 +3656,7 @@ sub run_highlighter {
 
 	close $fd;
 	open $fd, quote_command(git_cmd(), "cat-file", "blob", $hash)." | ".
+	          "col -bx | ".
 	          quote_command($highlight_bin).
 	          " --replace-tabs=8 --fragment --syntax $syntax |"
 		or die_error(500, "Couldn't open file or run syntax highlighter");
-- 
1.7.5.4

^ permalink raw reply related

* Re: Is there a scriptable way to update the stat-info in the index without having git open and read those files?
From: Junio C Hamano @ 2011-08-22 22:49 UTC (permalink / raw)
  To: Elijah Newren; +Cc: Git Mailing List
In-Reply-To: <CABPp-BEiN7ffNmvLCvEfz056M_F36j+gV9t6J9-x_=H9q0rZFw@mail.gmail.com>

Elijah Newren <newren@gmail.com> writes:

> A little more detail, for the curious: I have a script that is, among
> other things, renaming large numbers of files.  Calling 'git mv <old>
> <new>' on each pair took forever.  So I switched to manually renaming
> the files in the working copy myself, and using git update-index
> --index-info to do the renames in the index.  The result was _much_
> faster, but of course that method blows away all the stat information
> for the relevant files and causes any subsequent git operation (after
> my script is done) to be slow.  I inserted a 'git update-index -q
> --refresh' at the end of my script to fix that, but that is much
> slower than I want since it has to re-read all the affected files to
> ensure they haven't been modified (however, it isn't as slow as
> forking many git-mv processes).  I've tried to look for a way to speed
> up this update, but haven't found one.

Sounds like a one-off thing to me, and I personally do not think it is
worth the effort to add something even riskier than assume-unchanged to
solve.

^ permalink raw reply

* Re: [PATCH 0/2] Add an update=none option for 'loose' submodules
From: Junio C Hamano @ 2011-08-22 22:42 UTC (permalink / raw)
  To: Heiko Voigt; +Cc: git, Jens Lehmann
In-Reply-To: <20110822200052.GC11745@sandbox-rc>

Heiko Voigt <hvoigt@hvoigt.net> writes:

> On Mon, Aug 15, 2011 at 01:37:53PM -0700, Junio C Hamano wrote:
>> Heiko Voigt <hvoigt@hvoigt.net> writes:
>> 
>> > On Thu, Aug 11, 2011 at 11:28:31AM -0700, Junio C Hamano wrote:
>> >> Heiko Voigt <hvoigt@hvoigt.net> writes:
>> >> > We have been talking about loose submodules for some time:
>> >> 
>> >> Also before introducing a new terminology "loose submodule", please define
>> ... 
>> That sounds like a good thing to do.
> 
> I discovered that I only talked in the cover letter about the term
> 'loose'. Since that will not go into any commit I guess we can keep the
> series this way?

Yes, except that I do not have a clear answer to my other half of the
question in the same message you omitted from your quote.

>> What I usually do is say "submodule init" without any extra option once.
>> That will register all submodules from .gitmodules in the config. Now
>> when I say "submodule update" all submodules would be cloned. In the
>> case of recursive submodules actually
>>
>> 	git submodule update --init --recursive
>>
>> is the only command which can get you really everything in one go.
>>
>> Do you think the "submodule init" behavior is wrong? If so I think its a
>> bit late to change this since people using submodules (me included)
>> already have got used to it.
>>
>> With this config variable all submodules will still be registered to
>> .git/config on "submodule init" but "submodule update" will skip those
>> submodules.
>
> Ok, that sort-of makes sense, but we have been using "do we have the
> submodule registered in the .git/config of the superproject?" to decide
> "does the user interested in having a checkout of the submodule?" (I think
> in the ancient days it was "do we have .git in that submodule directory?"
> that decided it, but we dropped that because it won't work when switching
> branches that has and does not have the submodule in superproject).
>
> It is somewhat worrying that some parts of the system may still be using
> that old criteria "do we have it in .git/config of the superproject?" to
> decide if the user is interested in the submodule. If so they need to be
> updated to take this new semantics "do we have it in .git/config without
> its submodule.$name.update set to none" into account. We would probably
> need to have a paragraph in the release notes to warn about the semantics
> change (which I tend to agree with you that it is a good one).

^ permalink raw reply

* Re: Restoring timestamps (Re: Branches & directories)
From: Hilco Wijbenga @ 2011-08-22 22:33 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Kyle Moffett, Michael Witten, Junio C Hamano, Evan Shelhamer,
	Git Mailing List
In-Reply-To: <20110822210141.GA3880@elie.gateway.2wire.net>

On 22 August 2011 14:01, Jonathan Nieder <jrnieder@gmail.com> wrote:
> Hilco Wijbenga wrote:
>> On 22 August 2011 12:31, Kyle Moffett <kyle@moffetthome.net> wrote:
>
>>> (1) The GIT data-structures simply have no place for file timestamps, and
>>> "git stash" is simply a special way of dumping files into a temporary commit.
>>
>> That's what I thought. The "intentionally" threw me off. It's not
>> intentional, it's just a side effect.
>
> For what it's worth: no, it's intentional.  See, for example:
>
>  http://thread.gmane.org/gmane.comp.version-control.git/1564/focus=1680
>  https://git.wiki.kernel.org/index.php/GitFaq#Why_isn.27t_Git_preserving_modification_time_on_files.3F

After I had sent the above I realized it was worded a bit too strong.

> That said, something being intentional does not necessarily mean it is
> always _right_.  So, for example, patches to allow a commit to store
> some timestamps, with documentation explaining when this is
> appropriate, would probably be welcome.  Maybe a good place to store
> such information would be a dotfile alongside the file (so old,
> unaware git versions could extract the same information without fuss).

You mean an extra dotfile per file in the commit?

> Even if this feature were implemented just for "git stash", personally
> I would turn it off so "make" could continue to behave as I expect it
> to.  But in principle, I don't mind the idea of it existing. :)

Given that apparently the majority of Git users don't want/need this,
it should probably be off by default. So you would not even need to
turn it off. :-)

In fact, I would not want it on by default either. It's really only
useful when switching branches when I want to keep the exact state of
the branch.

^ permalink raw reply

* Is there a scriptable way to update the stat-info in the index without having git open and read those files?
From: Elijah Newren @ 2011-08-22 22:28 UTC (permalink / raw)
  To: Git Mailing List

Hi,

I want to do something really close to
  git update-index -q --refresh
However, I want it to assume the files in the working tree are
unmodified from the index (i.e. don't waste time opening and reading
the file) and simply update the stat information in the index to match
the current files on disk.

Yes, I know that would be unsafe if the files don't have the
appropriate contents; I'm promising that they do have the appropriate
contents and don't want to pay the performance penalty for git to
verify.  Is that possible?


A little more detail, for the curious: I have a script that is, among
other things, renaming large numbers of files.  Calling 'git mv <old>
<new>' on each pair took forever.  So I switched to manually renaming
the files in the working copy myself, and using git update-index
--index-info to do the renames in the index.  The result was _much_
faster, but of course that method blows away all the stat information
for the relevant files and causes any subsequent git operation (after
my script is done) to be slow.  I inserted a 'git update-index -q
--refresh' at the end of my script to fix that, but that is much
slower than I want since it has to re-read all the affected files to
ensure they haven't been modified (however, it isn't as slow as
forking many git-mv processes).  I've tried to look for a way to speed
up this update, but haven't found one.  Did I miss it?

Thanks,
Elijah

^ permalink raw reply

* Re: [PATCH v4 1/2] push: Don't push a repository with unpushed submodules
From: Junio C Hamano @ 2011-08-22 22:22 UTC (permalink / raw)
  To: Heiko Voigt; +Cc: Fredrik Gustafsson, git, jens.lehmann
In-Reply-To: <20110822194728.GA11745@sandbox-rc>

Heiko Voigt <hvoigt@hvoigt.net> writes:

> Junio since you are one person listed in the api docs could you maybe
> quickly explain to me what this flag is used for?

It is used in order to avoid walking the object we have walked already.

Which in turn means that once you walk chain of objects, unless you
remember the ones you walked and clear the marks after you are done, you
cannot walk the object chain for unrelated purposes.  See how functions
like get_merge_bases_many() walk portions of graph for their own purpose
and then avoid disrupting others by calling clear_commit_marks(). The use
of TMP_MARK (and its clearing after the function is done with the marked
objects) in remove_duplicate_parents() serve the same purpose.

^ permalink raw reply

* Re: [PATCH v2] add technical documentation about ref iteration
From: Junio C Hamano @ 2011-08-22 22:01 UTC (permalink / raw)
  To: Heiko Voigt; +Cc: git
In-Reply-To: <20110822203645.GD11745@sandbox-rc>

Heiko Voigt <hvoigt@hvoigt.net> writes:

> Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
> ---
>
> Hi,
>
> this is an update of the previous doc patch.

Looks very good; thanks.

^ permalink raw reply

* Re: [PATCH v2 0/1] git-clone: fix relative path problem in the alternates
From: Junio C Hamano @ 2011-08-22 21:57 UTC (permalink / raw)
  To: Hui Wang; +Cc: git
In-Reply-To: <7vzkj1uqpa.fsf@alter.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

> While at it, we may probably want to update the command option handling so
> that you can give more than one --reference= parameters.

Geez. There appear to be more bugs in the existing code.

If you

 - specify --reference;
 - the source of the clone is a local directory;
 - you do not specify --shared; and
 - the source of the clone has its own alternates

we end up exercising this call flow:

	init_db();
        setup_reference();
        -> add_to_alternates_file();
           This writes objects/info/alternates in the new repository
	clone_local();
        -> copy_or_link_directory(src/objects, dst/objects);
           -> copy_or_link_directory(src/objects/info, dst/objects/info);
              -> unlink(dst/objects/info/alternates);
                 link(src/objects/info/alternates, dst/objects/info/alternates);

and lose the --reference given from the command line.

The problem you are trying to address is a valid one, but it needs to be
fixed by teaching copy-or-link-directory that objects/info/alternates is
special. We need a more proper fix than "just let the recursive copy do a
possibly wrong thing and then patch it up if it is wrong", which is the
approach taken by your patch.

^ permalink raw reply

* Re: Malformed branch name in fast-export when specifying non-HEAD/branch revision
From: Jeff King @ 2011-08-22 21:32 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Sverre Rabbelier, Elijah Newren, Owen Stephens, git
In-Reply-To: <7vpqjxuogr.fsf@alter.siamese.dyndns.org>

On Mon, Aug 22, 2011 at 02:27:00PM -0700, Junio C Hamano wrote:

> Jeff King <peff@peff.net> writes:
> 
> > Yeah, the behavior of your patch looks fine to me. I thought the point
> > in contention was that having export understand refspecs would fix a lot
> > of _other_ cases, too.
> 
> Perhaps if we added refspecs we could cover other cases, too, but I do not
> think we need to require the patch to cover additional cases. The more
> problematic was that the particular implementation in the patch smelled
> bad.

OK. I didn't look at that at all. I just wanted to express my support
for "refspecs would solve other problems, too". :)

-Peff

^ permalink raw reply

* Re: Malformed branch name in fast-export when specifying non-HEAD/branch revision
From: Junio C Hamano @ 2011-08-22 21:27 UTC (permalink / raw)
  To: Jeff King
  Cc: Sverre Rabbelier, Junio C Hamano, Elijah Newren, Owen Stephens,
	git
In-Reply-To: <20110822175705.GB1945@sigill.intra.peff.net>

Jeff King <peff@peff.net> writes:

> Yeah, the behavior of your patch looks fine to me. I thought the point
> in contention was that having export understand refspecs would fix a lot
> of _other_ cases, too.

Perhaps if we added refspecs we could cover other cases, too, but I do not
think we need to require the patch to cover additional cases. The more
problematic was that the particular implementation in the patch smelled
bad.

^ permalink raw reply

* Restoring timestamps (Re: Branches & directories)
From: Jonathan Nieder @ 2011-08-22 21:01 UTC (permalink / raw)
  To: Hilco Wijbenga
  Cc: Kyle Moffett, Michael Witten, Junio C Hamano, Evan Shelhamer,
	Git Mailing List
In-Reply-To: <CAE1pOi1axNmGaPVXqBH02x0N=Z6tgO9R00RTokuJm50eY-OoNg@mail.gmail.com>

Hilco Wijbenga wrote:
> On 22 August 2011 12:31, Kyle Moffett <kyle@moffetthome.net> wrote:

>> (1) The GIT data-structures simply have no place for file timestamps, and
>> "git stash" is simply a special way of dumping files into a temporary commit.
>
> That's what I thought. The "intentionally" threw me off. It's not
> intentional, it's just a side effect.

For what it's worth: no, it's intentional.  See, for example:

 http://thread.gmane.org/gmane.comp.version-control.git/1564/focus=1680
 https://git.wiki.kernel.org/index.php/GitFaq#Why_isn.27t_Git_preserving_modification_time_on_files.3F

That said, something being intentional does not necessarily mean it is
always _right_.  So, for example, patches to allow a commit to store
some timestamps, with documentation explaining when this is
appropriate, would probably be welcome.  Maybe a good place to store
such information would be a dotfile alongside the file (so old,
unaware git versions could extract the same information without fuss).

Even if this feature were implemented just for "git stash", personally
I would turn it off so "make" could continue to behave as I expect it
to.  But in principle, I don't mind the idea of it existing. :)

Hope that helps,
Jonathan

^ permalink raw reply

* Re* [PATCH 1/2] clone: allow to clone from .git file
From: Junio C Hamano @ 2011-08-22 21:01 UTC (permalink / raw)
  To: Nguyen Thai Ngoc Duy; +Cc: git
In-Reply-To: <7vbovhw9pb.fsf@alter.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

> Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:
>
>>> Didn't somebody add "is this '.git' thing a valid git metadirectory?" API
>>> quite recently for exactly this?
>>
>> You mean resolve_gitdir() in abc0682 (rev-parse: add option
>> --resolve-git-dir <path> - 2011-08-15)? That function would barf on a
>> bundle file.
>
> Well, then it has to be fixed, perhaps to return NULL instead as other
> failure cases, as read_gitfile_GENTLY() should be gentle to the callers so
> that they can notice error cases and deal with them themselves.

The attached patch would be such a fix. While I think it is a necessary
thing to do independently from the issue you are trying to solve, I do not
think it is appropriate, as it tries to _read_ the whole thing before
deciding if it is a valid gitfile. You need a way to cheaply probe if it
is a bundle or a gitfile without reading the whole thing for your topic.

-- >8 --
Subject: [PATCH] fix misnamed read_gitfile_gently()

The function was not gentle at all to the callers and died without giving
them a chance to deal with possible errors. Rename it to read_gitfile(),
update all the callers, and add "gently" variant.

As nobody needs gently variant right now, it may be a good idea to just
rename the function without any other change for now, though...

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---

 builtin/init-db.c |    2 +-
 cache.h           |    9 +++++++-
 environment.c     |    2 +-
 path.c            |    2 +-
 refs.c            |    2 +-
 setup.c           |   59 ++++++++++++++++++++++++++++++++++++++++------------
 submodule.c       |    6 ++--
 7 files changed, 60 insertions(+), 22 deletions(-)

diff --git a/builtin/init-db.c b/builtin/init-db.c
index 025aa47..d07554c 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -347,7 +347,7 @@ static void separate_git_dir(const char *git_dir)
 		const char *src;
 
 		if (S_ISREG(st.st_mode))
-			src = read_gitfile_gently(git_link);
+			src = read_gitfile(git_link);
 		else if (S_ISDIR(st.st_mode))
 			src = git_link;
 		else
diff --git a/cache.h b/cache.h
index e11cf6a..9ce04a5 100644
--- a/cache.h
+++ b/cache.h
@@ -420,7 +420,14 @@ extern char *get_index_file(void);
 extern char *get_graft_file(void);
 extern int set_git_dir(const char *path);
 extern const char *get_git_work_tree(void);
-extern const char *read_gitfile_gently(const char *path);
+extern const char *read_gitfile(const char *path);
+enum {
+	ERROR_READ_GITFILE_CANTOPEN = 1,
+	ERROR_READ_GITFILE_READFAIL,
+	ERROR_READ_GITFILE_FORMAT,
+	ERROR_READ_GITFILE_BADDIR
+};
+extern const char *read_gitfile_gently(const char *path, int *status);
 extern void set_git_work_tree(const char *tree);
 
 #define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
diff --git a/environment.c b/environment.c
index 94d58fd..2228c4e 100644
--- a/environment.c
+++ b/environment.c
@@ -91,7 +91,7 @@ static void setup_git_env(void)
 	git_dir = getenv(GIT_DIR_ENVIRONMENT);
 	git_dir = git_dir ? xstrdup(git_dir) : NULL;
 	if (!git_dir) {
-		git_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
+		git_dir = read_gitfile(DEFAULT_GIT_DIR_ENVIRONMENT);
 		git_dir = git_dir ? xstrdup(git_dir) : NULL;
 	}
 	if (!git_dir)
diff --git a/path.c b/path.c
index 4d73cc9..6f3f5d5 100644
--- a/path.c
+++ b/path.c
@@ -139,7 +139,7 @@ char *git_path_submodule(const char *path, const char *fmt, ...)
 		strbuf_addch(&buf, '/');
 	strbuf_addstr(&buf, ".git");
 
-	git_dir = read_gitfile_gently(buf.buf);
+	git_dir = read_gitfile(buf.buf);
 	if (git_dir) {
 		strbuf_reset(&buf);
 		strbuf_addstr(&buf, git_dir);
diff --git a/refs.c b/refs.c
index b10419a..c98c006 100644
--- a/refs.c
+++ b/refs.c
@@ -451,7 +451,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *re
 	memcpy(gitdir + len, "/.git", 6);
 	len += 5;
 
-	tmp = read_gitfile_gently(gitdir);
+	tmp = read_gitfile(gitdir);
 	if (tmp) {
 		free(gitdir);
 		len = strlen(tmp);
diff --git a/setup.c b/setup.c
index ce87900..1f4d8dd 100644
--- a/setup.c
+++ b/setup.c
@@ -373,9 +373,11 @@ static int check_repository_format_gently(const char *gitdir, int *nongit_ok)
 
 /*
  * Try to read the location of the git directory from the .git file,
- * return path to git directory if found.
+ * return path to git directory if found. Pass a pointer to an int
+ * to receive error code and handle error yourself, or NULL to get
+ * this function die for you on errors.
  */
-const char *read_gitfile_gently(const char *path)
+const char *read_gitfile_gently(const char *path, int *status)
 {
 	char *buf;
 	char *dir;
@@ -389,20 +391,39 @@ const char *read_gitfile_gently(const char *path)
 	if (!S_ISREG(st.st_mode))
 		return NULL;
 	fd = open(path, O_RDONLY);
-	if (fd < 0)
-		die_errno("Error opening '%s'", path);
+	if (fd < 0) {
+		if (!status)
+			die_errno("Error opening '%s'", path);
+		*status = ERROR_READ_GITFILE_CANTOPEN;
+		return NULL;
+	}
 	buf = xmalloc(st.st_size + 1);
 	len = read_in_full(fd, buf, st.st_size);
 	close(fd);
-	if (len != st.st_size)
-		die("Error reading %s", path);
+	if (len != st.st_size) {
+		if (!status)
+			die("Error reading %s", path);
+		*status = ERROR_READ_GITFILE_READFAIL;
+		free(buf);
+		return NULL;
+	}
 	buf[len] = '\0';
-	if (prefixcmp(buf, "gitdir: "))
-		die("Invalid gitfile format: %s", path);
+	if (prefixcmp(buf, "gitdir: ")) {
+		if (!status)
+			die("Invalid gitfile format: %s", path);
+		*status = ERROR_READ_GITFILE_FORMAT;
+		free(buf);
+		return NULL;
+	}
 	while (buf[len - 1] == '\n' || buf[len - 1] == '\r')
 		len--;
-	if (len < 9)
-		die("No path in gitfile: %s", path);
+	if (len < 9) {
+		if (!status)
+			die("No path in gitfile: %s", path);
+		*status = ERROR_READ_GITFILE_FORMAT;
+		free(buf);
+		return NULL;
+	}
 	buf[len] = '\0';
 	dir = buf + 8;
 
@@ -417,14 +438,24 @@ const char *read_gitfile_gently(const char *path)
 		buf = dir;
 	}
 
-	if (!is_git_directory(dir))
-		die("Not a git repository: %s", dir);
+	if (!is_git_directory(dir)) {
+		if (!status)
+			die("Not a git repository: %s", dir);
+		*status = ERROR_READ_GITFILE_BADDIR;
+		free(buf);
+		return NULL;
+	}
 	path = real_path(dir);
 
 	free(buf);
 	return path;
 }
 
+const char *read_gitfile(const char *path)
+{
+	return read_gitfile_gently(path, NULL);
+}
+
 static const char *setup_explicit_git_dir(const char *gitdirenv,
 					  char *cwd, int len,
 					  int *nongit_ok)
@@ -437,7 +468,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 	if (PATH_MAX - 40 < strlen(gitdirenv))
 		die("'$%s' too big", GIT_DIR_ENVIRONMENT);
 
-	gitfile = (char*)read_gitfile_gently(gitdirenv);
+	gitfile = (char*)read_gitfile(gitdirenv);
 	if (gitfile) {
 		gitfile = xstrdup(gitfile);
 		gitdirenv = gitfile;
@@ -661,7 +692,7 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
 	if (one_filesystem)
 		current_device = get_device_or_die(".", NULL);
 	for (;;) {
-		gitfile = (char*)read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
+		gitfile = (char*)read_gitfile(DEFAULT_GIT_DIR_ENVIRONMENT);
 		if (gitfile)
 			gitdirenv = gitfile = xstrdup(gitfile);
 		else {
diff --git a/submodule.c b/submodule.c
index b6dec70..b8b0326 100644
--- a/submodule.c
+++ b/submodule.c
@@ -32,7 +32,7 @@ static int add_submodule_odb(const char *path)
 	const char *git_dir;
 
 	strbuf_addf(&objects_directory, "%s/.git", path);
-	git_dir = read_gitfile_gently(objects_directory.buf);
+	git_dir = read_gitfile(objects_directory.buf);
 	if (git_dir) {
 		strbuf_reset(&objects_directory);
 		strbuf_addstr(&objects_directory, git_dir);
@@ -478,7 +478,7 @@ int fetch_populated_submodules(int num_options, const char **options,
 		strbuf_addf(&submodule_path, "%s/%s", work_tree, ce->name);
 		strbuf_addf(&submodule_git_dir, "%s/.git", submodule_path.buf);
 		strbuf_addf(&submodule_prefix, "%s%s/", prefix, ce->name);
-		git_dir = read_gitfile_gently(submodule_git_dir.buf);
+		git_dir = read_gitfile(submodule_git_dir.buf);
 		if (!git_dir)
 			git_dir = submodule_git_dir.buf;
 		if (is_directory(git_dir)) {
@@ -516,7 +516,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)
 	const char *git_dir;
 
 	strbuf_addf(&buf, "%s/.git", path);
-	git_dir = read_gitfile_gently(buf.buf);
+	git_dir = read_gitfile(buf.buf);
 	if (!git_dir)
 		git_dir = buf.buf;
 	if (!is_directory(git_dir)) {

^ permalink raw reply related

* Re: [PATCH v2 0/1] git-clone: fix relative path problem in the alternates
From: Junio C Hamano @ 2011-08-22 20:38 UTC (permalink / raw)
  To: Hui Wang; +Cc: git
In-Reply-To: <7v7h65w9d7.fsf@alter.siamese.dyndns.org>

Junio C Hamano <gitster@pobox.com> writes:

>> 3. current existing add_to_alternates_file() will unconditionally append
>> "/objects" at each new added line, that need us to parse and  remove
>> "/objects" from each line read out from source alternates, this is a little
>> bit complicated.
>
> Clone with --reference is the only other caller of that function; I would
> say it is perfectly fine to make it the caller's responsibility to append
> "/objects" if that makes the resulting code easier to maintain.

I would further suggest moving add_to_alternates_file() from sha1_file.c
to builtin/clone.c and make it file-scope static function, and change the
way it should be used.

 - The caller should first obtain a lock file to info/alternates. If it
   truncates first or opens the file for appending is up to the caller.

 - When adding an alternate (either from --reference or your new
   codepath), the caller should give the lockfile instance it obtained
   earlier, and a path to the object store it wants to borrow objects from
   (not the repository, i.e. the caller should add "/objects" at the end
   if needed before calling the function), to add_to_alternates_file()
   function;

 - The function should just write the path to the locked info/alternates
   file, and link it to alt_odb list. Do not commit the alternates file,
   to allow multiple calls to the function be made without opening and
   closing the file number of times.

 - The caller should commit the updated alternates file once it is done.

While at it, we may probably want to update the command option handling so
that you can give more than one --reference= parameters.

^ permalink raw reply

* [PATCH v2] add technical documentation about ref iteration
From: Heiko Voigt @ 2011-08-22 20:36 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vei12b9aq.fsf@alter.siamese.dyndns.org>

Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
---

Hi,

this is an update of the previous doc patch.

On Wed, Aug 03, 2011 at 12:10:37PM -0700, Junio C Hamano wrote:
> Heiko Voigt <hvoigt@hvoigt.net> writes:
> > +Submodules
> > +----------
> > +
> > +If you want to iterate the refs of a submodule you first need to call
> > +
> > +	add_submodule_odb(submodule)
> > +
> > +and test whether that succeeds.
> 
> Hmm, this should probably be explained a bit deeper or not at all. For
> example, what is "submodule" here? A path to the submodule directory? The
> name of submodule? What is the unwanted consequence of adding this extra
> object database into your process (e.g. you can no longer tell if an
> object exists in the superproject, as it may now come from the submodule's
> object database)? Can you get rid of it? How does this function signal
> failures? What is the symptom if you forget this call and used the
> iteration in the submodule (e.g. "we do not see any ref"; "we see only
> some ref but not all"; "the call crashes the process")?

I hope I answered all these questions in the patch below.

> 
> > +
> > +(Heiko Voigt)
> 
> Please drop this line for two reasons.

Dropped.

 Documentation/technical/api-ref-iteration.txt |   81 +++++++++++++++++++++++++
 1 files changed, 81 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/technical/api-ref-iteration.txt

diff --git a/Documentation/technical/api-ref-iteration.txt b/Documentation/technical/api-ref-iteration.txt
new file mode 100644
index 0000000..dbbea95
--- /dev/null
+++ b/Documentation/technical/api-ref-iteration.txt
@@ -0,0 +1,81 @@
+ref iteration API
+=================
+
+
+Iteration of refs is done by using an iterate function which will call a
+callback function for every ref. The callback function has this
+signature:
+
+	int handle_one_ref(const char *refname, const unsigned char *sha1,
+			   int flags, void *cb_data);
+
+There are different kinds of iterate functions which all take a
+callback of this type. The callback is then called for each found ref
+until the callback returns nonzero. The returned value is then also
+returned by the iterate function.
+
+Iteration functions
+-------------------
+
+* `head_ref()` just iterates the head ref.
+
+* `for_each_ref()` iterates all refs.
+
+* `for_each_ref_in()` iterates all refs which have a defined prefix and
+  strips that prefix from the passed variable refname.
+
+* `for_each_tag_ref()`, `for_each_branch_ref()`, `for_each_remote_ref()`,
+  `for_each_replace_ref()` iterate refs from the respective area.
+
+* `for_each_glob_ref()` iterates all refs that match the specified glob
+  pattern.
+
+* `for_each_glob_ref_in()` the previous and `for_each_ref_in()` combined.
+
+* `head_ref_submodule()`, `for_each_ref_submodule()`,
+  `for_each_ref_in_submodule()`, `for_each_tag_ref_submodule()`,
+  `for_each_branch_ref_submodule()`, `for_each_remote_ref_submodule()`
+  do the same as the functions descibed above but for a specified
+  submodule.
+
+* `for_each_rawref()` can be used to learn about broken ref and symref.
+
+* `for_each_reflog()` iterates each reflog file.
+
+Submodules
+----------
+
+If you want to iterate the refs of a submodule you first need to add the
+submodules object database. You can do this by a code-snippet like
+this:
+
+	const char *path = "path/to/submodule"
+	if (!add_submodule_odb(path))
+		die("Error submodule '%s' not populated.", path);
+
+`add_submodule_odb()` will return an non-zero value on success. If you
+do not do this you will get an error for each ref that it does not point
+to a valid object.
+
+Note: As a side-effect of this you can not safely assume that all
+objects you lookup are available in superproject. All submodule objects
+will be available the same way as the superprojects objects.
+
+Example:
+--------
+
+----
+static int handle_remote_ref(const char *refname,
+		const unsigned char *sha1, int flags, void *cb_data)
+{
+	struct strbuf *output = cb_data;
+	strbuf_addf(output, "%s\n", refname);
+	return 0;
+}
+
+...
+
+	struct strbuf output = STRBUF_INIT;
+	for_each_remote_ref(handle_remote_ref, &output);
+	printf("%s", output.buf);
+----
-- 
1.7.6.351.g9ce65.dirty

^ permalink raw reply related

* Re: [Git 1.7.6.557.gcee4] git stash
From: Hilco Wijbenga @ 2011-08-22 20:15 UTC (permalink / raw)
  To: Brandon Casey; +Cc: David Caldwell, Git Users
In-Reply-To: <fbFntd6r8tmN4NcET9Ya3OWDfsrxz1tfPv7GaddGfwwdirG8AgjrG8ARoR2-ZhadzpRI2DU2ZtTGdWAUGJeUZuBXmxWX5eSmT16u5cBjtec@cipher.nrlssc.navy.mil>

On 22 August 2011 12:58, Brandon Casey
<brandon.casey.ctr@nrlssc.navy.mil> wrote:
> On 08/22/2011 01:43 PM, Hilco Wijbenga wrote:
>> On 22 August 2011 10:15, Brandon Casey
>> <brandon.casey.ctr@nrlssc.navy.mil> wrote:
>>> On 08/22/2011 01:01 AM, Hilco Wijbenga wrote:
>>>> Hi David,
>>>>
>>>> I noticed your very timely change to git stash in the current master
>>>> branch. I tried it but it doesn't behave as I was expecting/hoping.
>>>
>>> It looks like it is actually creating the stash correctly, but it's
>>> just not deleting the ignored directory.
>
>>> Something like this is probably the appropriate fix:
>>>
>>> diff --git a/git-stash.sh b/git-stash.sh
>>> index f4e6f05..a2d4b4d 100755
>>> --- a/git-stash.sh
>>> +++ b/git-stash.sh
>>> @@ -240,7 +240,7 @@ save_stash () {
>>>                test "$untracked" = "all" && CLEAN_X_OPTION=-x || CLEAN_X_OPTION
>>>                if test -n "$untracked"
>>>                then
>>> -                       git clean --force --quiet $CLEAN_X_OPTION
>>> +                       git clean --force --quiet -d $CLEAN_X_OPTION
>>>                fi
>>>
>>>                if test "$keep_index" = "t" && test -n $i_tree
>>>
>>> Needs tests.
>>
>> I just tried it with the extra -d and it all seems to work
>> beautifully. Should your patch be sent anywhere?
>
> It needs a couple of tests added to t/t3905-stash-include-untracked.sh
> to demonstrate that this functionality works correctly and to ensure
> that it doesn't break in the future.
>
> Need tests at least for:
>
>   --all stashes untracked / ignored in subdirectory
>   --include-untracked stashes untracked in subdirectory, leaves ignored alone
>
> Do we currently test that stash leaves untracked / ignored alone when
> --all or --include-untracked are not supplied?
>
> And it needs a commit message following the guidelines in
> Documentation/SubmittingPatches.  Then it can be submitted to this list
> using format-patch and send-email.  Interested??? :)  otherwise I'll try
> to get to it later tonight.

Interested? Sure. Do I have the time? Unfortunately not. I'm
overworked as it is. :-( Well, maybe in the weekend. But this would be
a major operation for me because it's all new.

^ permalink raw reply

* Re: Branches & directories
From: Hilco Wijbenga @ 2011-08-22 20:10 UTC (permalink / raw)
  To: Kyle Moffett
  Cc: Michael Witten, Junio C Hamano, Evan Shelhamer, Git Mailing List
In-Reply-To: <CAGZ=bqLyS9tcpqztwGWFOXtDJRhugu+JYvz7wTnc0PTmECWX2g@mail.gmail.com>

On 22 August 2011 12:31, Kyle Moffett <kyle@moffetthome.net> wrote:
> On Mon, Aug 22, 2011 at 14:49, Hilco Wijbenga <hilco.wijbenga@gmail.com> wrote:
>> On 22 August 2011 05:46, Kyle Moffett <kyle@moffetthome.net> wrote:
>>> On Mon, Aug 22, 2011 at 01:36, Hilco Wijbenga <hilco.wijbenga@gmail.com> wrote:
>>>> On 21 August 2011 20:01, Kyle Moffett <kyle@moffetthome.net> wrote:
>>>>> Obviously the easiest way to work around that issue is "git clean",
>>>>> which has options to select all untracked files or just ignored ones.
>>>>
>>>> As I mentioned above, I don't want to *delete* untracked/ignored
>>>> files, I just want them to stick to the branch I was working on. So if
>>>> I change to a different branch I get the appropriate build artifacts.
>>>>
>>>> Something like: git stash --everything "All artifacts for
>>>> this-branch." && git checkout other-branch && git stash apply
>>>> stash-for-other-branch.
>>>
>>> When I am in those sorts of situations I generally just use separate
>>> working directories or separate checkouts entirely; if you really prefer
>>> to have everything in one directory you would be better served by
>>> integrating "ccache" into your workflow.
>>
>> Unfortunately, that seems for C/C++ code only. I use Java. Besides,
>> it's not the Java compilation that takes most of the time.
>
> Hm, that sounds like a very serious Eclipse limitation with almost all forms
> of source control.  What is done with other VCSes (IE: Subversion, etc)?

It has nothing to do with Eclipse. There is just a lot going on in the build.

> From this I believe the best option is to just make use of multiple separate
> checkouts or worktrees.

Sounds like it.

>>> In particular, even "git stash" intentionally does not preserve file times,
>>> so you would end up rebuilding everything anyways because all of your
>>> source files would be as new as your object files.
>>
>> Yes, I just noticed that. Why do you say "intentionally"? Is extra
>> work being done to make it so? If yes, then shouldn't that be
>> configurable?
>
> Well, there's 2 reasons:
>
> (1) The GIT data-structures simply have no place for file timestamps, and
> "git stash" is simply a special way of dumping files into a temporary commit.

That's what I thought. The "intentionally" threw me off. It's not
intentional, it's just a side effect.

> This is exactly the same as the

There seems to be some text missing here?

> (2) You almost always *don't* want to preserve timestamps.  For example:
>
> $ git checkout -b my-feature origin/master
> $ vim some-file.c
> $ make
> $ git add some-file.c && git commit -m "A new feature"
> $ git checkout -b my-bugfix origin/master
> $ vim other-file.c
> $ make
>
> If GIT preserved timestamps, the second "make" would fail to rebuild the
> product "some-file.o" because "some-file.c" is still older than it, even
> though "some-file.c" has changed since the last build!!!
>
> Really, GIT is only intended for storing source code.  If you want to store
> other kinds of things (like timestamps, permissions, etc), then you need to
> turn them into source code (IE: a text file and a "make install" target) and
> then store them that way.

Yep, that all makes sense. I just wish there was at least an option to
keep the timestamp (and possibly other such things). Even Subversion
can do that... ;-) After all, not everybody uses C & make.

Cheers,
Hilco

^ permalink raw reply

* Re: Re: [PATCH 0/2] Add an update=none option for 'loose' submodules
From: Heiko Voigt @ 2011-08-22 20:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jens Lehmann
In-Reply-To: <7vy5yujtr2.fsf@alter.siamese.dyndns.org>

Hi,

On Mon, Aug 15, 2011 at 01:37:53PM -0700, Junio C Hamano wrote:
> Heiko Voigt <hvoigt@hvoigt.net> writes:
> 
> > On Thu, Aug 11, 2011 at 11:28:31AM -0700, Junio C Hamano wrote:
> >> Heiko Voigt <hvoigt@hvoigt.net> writes:
> >> > We have been talking about loose submodules for some time:
> >> 
> >> Also before introducing a new terminology "loose submodule", please define
> >> it somewhere. It feels confusing to me that a normal submodule, which
> >> shouldn't be auto-cloned nor auto-updated without "submodule init", needs
> >> to be called by a name other than simply a "submodule" but with an
> >> adjuctive "loose submodule".
> >
> > Thats why I avoided talking about it in the docs. For the commit message
> > I thought it would be kind of intuitive but I can update the commit
> > message so that it becomes more clear.
> 
> That sounds like a good thing to do.

I discovered that I only talked in the cover letter about the term
'loose'. Since that will not go into any commit I guess we can keep the
series this way?

Cheers Heiko

^ permalink raw reply

* Re: [Git 1.7.6.557.gcee4] git stash
From: Brandon Casey @ 2011-08-22 19:58 UTC (permalink / raw)
  To: Hilco Wijbenga; +Cc: David Caldwell, Git Users
In-Reply-To: <CAE1pOi2OnHpu+kBj8Z47nb7C-MHFpUMAc8ArG3haWpncEDQ-jA@mail.gmail.com>

On 08/22/2011 01:43 PM, Hilco Wijbenga wrote:
> On 22 August 2011 10:15, Brandon Casey
> <brandon.casey.ctr@nrlssc.navy.mil> wrote:
>> On 08/22/2011 01:01 AM, Hilco Wijbenga wrote:
>>> Hi David,
>>>
>>> I noticed your very timely change to git stash in the current master
>>> branch. I tried it but it doesn't behave as I was expecting/hoping.
>>
>> It looks like it is actually creating the stash correctly, but it's
>> just not deleting the ignored directory.

>> Something like this is probably the appropriate fix:
>>
>> diff --git a/git-stash.sh b/git-stash.sh
>> index f4e6f05..a2d4b4d 100755
>> --- a/git-stash.sh
>> +++ b/git-stash.sh
>> @@ -240,7 +240,7 @@ save_stash () {
>>                test "$untracked" = "all" && CLEAN_X_OPTION=-x || CLEAN_X_OPTION
>>                if test -n "$untracked"
>>                then
>> -                       git clean --force --quiet $CLEAN_X_OPTION
>> +                       git clean --force --quiet -d $CLEAN_X_OPTION
>>                fi
>>
>>                if test "$keep_index" = "t" && test -n $i_tree
>>
>> Needs tests.
> 
> I just tried it with the extra -d and it all seems to work
> beautifully. Should your patch be sent anywhere?

It needs a couple of tests added to t/t3905-stash-include-untracked.sh
to demonstrate that this functionality works correctly and to ensure
that it doesn't break in the future.

Need tests at least for:

   --all stashes untracked / ignored in subdirectory
   --include-untracked stashes untracked in subdirectory, leaves ignored alone

Do we currently test that stash leaves untracked / ignored alone when
--all or --include-untracked are not supplied?

And it needs a commit message following the guidelines in
Documentation/SubmittingPatches.  Then it can be submitted to this list
using format-patch and send-email.  Interested??? :)  otherwise I'll try
to get to it later tonight.

-Brandon

^ permalink raw reply

* Re: Re: [PATCH v4 1/2] push: Don't push a repository with unpushed submodules
From: Heiko Voigt @ 2011-08-22 19:47 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Fredrik Gustafsson, git, jens.lehmann
In-Reply-To: <7vmxf3xnsf.fsf@alter.siamese.dyndns.org>

Hi,

On Sat, Aug 20, 2011 at 11:48:48PM -0700, Junio C Hamano wrote:
> After removing the change to combine-diff.c from your two-patch series, I
> applied them on top of this one, and queued the result in 'pu'.
> 
> While I tried to be careful while doing this callback-for-combine-diff
> patch so that a callback function written for two-way diff can be used
> without any change as long as it does not care about the LHS (i.e. "one")
> of the filepair, please double check. I didn't read your change to
> submodule.c very carefully (and I didn't have to change it).
> 
> The result seems to pass your new tests ;-).

Very nice. Today I had a deeper look into the current tests for
on-demand and found a bug in them. Cleaning them up also revealed a bug
in the current code. Junio could you please squash this[1] in the last
patch (on-demand option).

I analysed the cause of this bug and it seems that we are not allowed to
iterate revisions using init_revisions() and setup_revisions() more
than once. I tracked this down to the SEEN flag in the struct object.
Junio since you are one person listed in the api docs could you maybe
quickly explain to me what this flag is used for?

I quickly tried to implement a reset_revision_walk function which will
reset this flag but it seems that this breaks some expectations in the
code since I got a segfault.

Cheers Heiko

[1]

diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh
index 35820ec..b0e94f7 100755
--- a/t/t5531-deep-submodule-push.sh
+++ b/t/t5531-deep-submodule-push.sh
@@ -124,6 +124,10 @@ test_expect_success 'push unpushed submodules' '
 		cd work &&
 		git checkout master &&
 		git push --recurse-submodules=on-demand ../pub.git master
+		cd gar/bage &&
+		git rev-parse master >expected &&
+		git rev-parse origin/master >actual &&
+		test_cmp expected actual
 	)
 '
 
@@ -132,10 +136,14 @@ test_expect_success 'push unpushed submodules when not needed' '
 		cd work &&
 		(
 			cd gar/bage &&
-			>junk4 &&
-			git add junk4 &&
-			git commit -m "junk4" &&
-			git push
+			git checkout master &&
+			>junk5 &&
+			git add junk5 &&
+			git commit -m "junk5" &&
+			git push &&
+			git rev-parse master >expected &&
+			git rev-parse origin/master >actual &&
+			test_cmp expected actual
 		) &&
 		git add gar/bage &&
 		git commit -m "updated submodule" &&
@@ -143,4 +151,20 @@ test_expect_success 'push unpushed submodules when not needed' '
 	)
 '
 
+test_expect_failure 'push unpushed submodules on-demand fails when submodule not pushable' '
+	(
+		cd work &&
+		(
+			cd gar/bage &&
+			git checkout HEAD~0 &&
+			>junk6 &&
+			git add junk6 &&
+			git commit -m "junk6"
+		) &&
+		git add gar/bage &&
+		git commit -m "updated submodule" &&
+		test_must_fail git push --recurse-submodules=on-demand ../pub.git master
+	)
+'
+
 test_done
-- 
1.7.6.46.g0f058

^ permalink raw reply related

* Re: Branches & directories
From: Kyle Moffett @ 2011-08-22 19:31 UTC (permalink / raw)
  To: Hilco Wijbenga
  Cc: Michael Witten, Junio C Hamano, Evan Shelhamer, Git Mailing List
In-Reply-To: <CAE1pOi0Er1ZgftpNeCr85Zu27xR2127V_KdAtvKc1NOKmDUvzQ@mail.gmail.com>

On Mon, Aug 22, 2011 at 14:49, Hilco Wijbenga <hilco.wijbenga@gmail.com> wrote:
> On 22 August 2011 05:46, Kyle Moffett <kyle@moffetthome.net> wrote:
>> On Mon, Aug 22, 2011 at 01:36, Hilco Wijbenga <hilco.wijbenga@gmail.com> wrote:
>>> On 21 August 2011 20:01, Kyle Moffett <kyle@moffetthome.net> wrote:
>>>> Obviously the easiest way to work around that issue is "git clean",
>>>> which has options to select all untracked files or just ignored ones.
>>>
>>> As I mentioned above, I don't want to *delete* untracked/ignored
>>> files, I just want them to stick to the branch I was working on. So if
>>> I change to a different branch I get the appropriate build artifacts.
>>>
>>> Something like: git stash --everything "All artifacts for
>>> this-branch." && git checkout other-branch && git stash apply
>>> stash-for-other-branch.
>>
>> When I am in those sorts of situations I generally just use separate
>> working directories or separate checkouts entirely; if you really prefer
>> to have everything in one directory you would be better served by
>> integrating "ccache" into your workflow.
>
> Unfortunately, that seems for C/C++ code only. I use Java. Besides,
> it's not the Java compilation that takes most of the time.

Hm, that sounds like a very serious Eclipse limitation with almost all forms
of source control.  What is done with other VCSes (IE: Subversion, etc)?

>From this I believe the best option is to just make use of multiple separate
checkouts or worktrees.

>> In particular, even "git stash" intentionally does not preserve file times,
>> so you would end up rebuilding everything anyways because all of your
>> source files would be as new as your object files.
>
> Yes, I just noticed that. Why do you say "intentionally"? Is extra
> work being done to make it so? If yes, then shouldn't that be
> configurable?

Well, there's 2 reasons:

(1) The GIT data-structures simply have no place for file timestamps, and
"git stash" is simply a special way of dumping files into a temporary commit.
This is exactly the same as the

(2) You almost always *don't* want to preserve timestamps.  For example:

$ git checkout -b my-feature origin/master
$ vim some-file.c
$ make
$ git add some-file.c && git commit -m "A new feature"
$ git checkout -b my-bugfix origin/master
$ vim other-file.c
$ make

If GIT preserved timestamps, the second "make" would fail to rebuild the
product "some-file.o" because "some-file.c" is still older than it, even
though "some-file.c" has changed since the last build!!!

Really, GIT is only intended for storing source code.  If you want to store
other kinds of things (like timestamps, permissions, etc), then you need to
turn them into source code (IE: a text file and a "make install" target) and
then store them that way.

Cheers,
Kyle Moffett

^ permalink raw reply

* Re: [PATCH v2 0/1] git-clone: fix relative path problem in the alternates
From: Junio C Hamano @ 2011-08-22 19:10 UTC (permalink / raw)
  To: Hui Wang; +Cc: git
In-Reply-To: <1314003957-9455-1-git-send-email-jason77.wang@gmail.com>

Hui Wang <jason77.wang@gmail.com> writes:

> 2. current git system only provides add_to_alternates_file()in the sha1_file.c
> to update lockfile, this function can add a line to lockfile but can't empty
> and write lockfile,

I do not see the need for "empty and write" in the first place. You are
spending cycles to go through all the lines in the input, inspecting and
holding the replacement somewhere, it is a one-time cost for cloning, and
the alternates file wouldn't be humongous anyway, so I do not see the need
for "we don't touch if there is no relative path in the file" if it makes
the code more complex than a stupid "one line at a time" approach.

> 3. current existing add_to_alternates_file() will unconditionally append
> "/objects" at each new added line, that need us to parse and  remove
> "/objects" from each line read out from source alternates, this is a little
> bit complicated.

Clone with --reference is the only other caller of that function; I would
say it is perfectly fine to make it the caller's responsibility to append
"/objects" if that makes the resulting code easier to maintain.

^ permalink raw reply

* Re: [PATCH 1/2] clone: allow to clone from .git file
From: Junio C Hamano @ 2011-08-22 19:02 UTC (permalink / raw)
  To: Nguyen Thai Ngoc Duy; +Cc: git
In-Reply-To: <CACsJy8BaCwT+fd-KORsqXqQEtWZUpTDwgoSGU9+pMfNdero5=Q@mail.gmail.com>

Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:

>> Didn't somebody add "is this '.git' thing a valid git metadirectory?" API
>> quite recently for exactly this?
>>
>
> You mean resolve_gitdir() in abc0682 (rev-parse: add option
> --resolve-git-dir <path> - 2011-08-15)? That function would barf on a
> bundle file.

Well, then it has to be fixed, perhaps to return NULL instead as other
failure cases, as read_gitfile_GENTLY() should be gentle to the callers so
that they can notice error cases and deal with them themselves.

^ permalink raw reply

* Re: Branches & directories
From: Hilco Wijbenga @ 2011-08-22 18:49 UTC (permalink / raw)
  To: Kyle Moffett
  Cc: Michael Witten, Junio C Hamano, Evan Shelhamer, Git Mailing List
In-Reply-To: <CAGZ=bqLZoLoyMcvnppg6SyFtJU8phSquQeBZ7uhwP=+ZL3DADw@mail.gmail.com>

On 22 August 2011 05:46, Kyle Moffett <kyle@moffetthome.net> wrote:
> On Mon, Aug 22, 2011 at 01:36, Hilco Wijbenga <hilco.wijbenga@gmail.com> wrote:
>> On 21 August 2011 20:01, Kyle Moffett <kyle@moffetthome.net> wrote:
>>> On Sun, Aug 21, 2011 at 22:13, Hilco Wijbenga <hilco.wijbenga@gmail.com> wrote:
>>>> Thanks for sticking it out. :-) That all makes sense. I think it's all
>>>> pretty clear now.
>>>
>>> It's worth mentioning that in most cases you DON'T want to delete untracked and
>>> ignored files when switching branches.
>>
>> For the record, I don't want them deleted but replaced with the
>> artifacts in the other branch. A bit wasteful but it saves a lot of
>> build time.
>>
>>> For example, when I'm doing kernel development, I will frequently do this:
>>>
>>> $ git checkout -b my-new-feature origin/master
>>> [...hack hack hack...]
>>> $ make -j16 && make install && reboot
>>> [...find unrelated bug...]
>>> $ git checkout -b my-new-bugfix origin/master
>>> [...fix the bug...]
>>> $ make -j16 && make install && reboot
>>> $ git commit -m 'I fixed this bug'
>>> $ git checkout my-new-feature
>>> $ git rebase my-new-bugfix
>>> $ make -j16 && make install && reboot
>>>
>>> To avoid wasting time I don't want to completely rebuild the kernel each
>>> and every time I switch branches, I just want to rebuild the files that
>>> changed when I switched.  The way GIT works lets me do that quite
>>> easily, and the kernel Makefiles detect the changed files and rebuild
>>> the minimum amount necessary.
>>>
>>> GIT's behavior when you switch between branches is effectively the
>>> same as applying a patch generated by diffing between the two
>>> branches.  Any files which would not be changed are left alone, their
>>> timestamps completely unchanged.
>>
>> For small changes that makes perfect sense. I'm at a stage where APIs
>> are still evolving and changing an API means rebuilding lots of code.
>> I'd like to avoid that.
>>
>>> It sounds like Eclipse is simply not detecting changes to your working
>>> tree by outside programs, and as a result it's not rebuilding files and
>>> indexes the way that it should.
>>
>> While Eclipse isn't great at detecting such changes, this isn't really
>> an Eclipse problem. It's just that lots of things are still changing
>> and that leads to lots of building.
>>
>>> Obviously the easiest way to work around that issue is "git clean",
>>> which has options to select all untracked files or just ignored ones.
>>
>> As I mentioned above, I don't want to *delete* untracked/ignored
>> files, I just want them to stick to the branch I was working on. So if
>> I change to a different branch I get the appropriate build artifacts.
>>
>> Something like: git stash --everything "All artifacts for
>> this-branch." && git checkout other-branch && git stash apply
>> stash-for-other-branch.
>
> When I am in those sorts of situations I generally just use separate
> working directories or separate checkouts entirely; if you really prefer
> to have everything in one directory you would be better served by
> integrating "ccache" into your workflow.

Unfortunately, that seems for C/C++ code only. I use Java. Besides,
it's not the Java compilation that takes most of the time.

> In particular, even "git stash" intentionally does not preserve file times,
> so you would end up rebuilding everything anyways because all of your
> source files would be as new as your object files.

Yes, I just noticed that. Why do you say "intentionally"? Is extra
work being done to make it so? If yes, then shouldn't that be
configurable?

Cheers,
Hilco

^ permalink raw reply

* Re: [Git 1.7.6.557.gcee4] git stash
From: Hilco Wijbenga @ 2011-08-22 18:43 UTC (permalink / raw)
  To: Brandon Casey; +Cc: David Caldwell, Git Users
In-Reply-To: <euT1_KmfLWaxwFqOd8u_Zv-flc6Wr9rvg1tf_39P-YMaH8T-tpKl94WG8yCIAmW0AMLjdqnjA3I2uGRQf9YpY513-Io-lue5aNPuVDv8Qp8@cipher.nrlssc.navy.mil>

On 22 August 2011 10:15, Brandon Casey
<brandon.casey.ctr@nrlssc.navy.mil> wrote:
> On 08/22/2011 01:01 AM, Hilco Wijbenga wrote:
>> Hi David,
>>
>> I noticed your very timely change to git stash in the current master
>> branch. I tried it but it doesn't behave as I was expecting/hoping.
>
> It looks like it is actually creating the stash correctly, but it's
> just not deleting the ignored directory.
>
> But, there is a small problem with your command sequence...
>
>> hilco@centaur ~/tmp/repo repo$ git --version
>> git version 1.7.6.557.gcee4
>> hilco@centaur ~/tmp/repo repo$ git init
>> Initialized empty Git repository in /home/hilco/tmp/repo/.git/
>> hilco@centaur ~/tmp/repo repo (master #)$ cat >>.gitignore <<- EOF
>>>         *.ignore
>>>         ignore-dir/
>>> EOF
>> hilco@centaur ~/tmp/repo repo (master #%)$ mkdir src
>> hilco@centaur ~/tmp/repo repo (master #%)$ touch file.txt src/code.txt
>> hilco@centaur ~/tmp/repo repo (master #%)$ git add -A .
>> hilco@centaur ~/tmp/repo repo (master #)$ git commit -m '1'
>> [master (root-commit) 0fb4106] 1
>>  1 files changed, 2 insertions(+), 0 deletions(-)
>>  create mode 100644 .gitignore
>>  create mode 100644 file.txt
>>  create mode 100644 src/code.txt
>> hilco@centaur ~/tmp/repo repo (master)$ touch file-a.ignore src/file-b.ignore
>> hilco@centaur ~/tmp/repo repo (master %)$ echo "hello">src/code.txt
>> hilco@centaur ~/tmp/repo repo (master *%)$ mkdir ignore-dir
>> hilco@centaur ~/tmp/repo repo (master *%)$ touch
>> ignore-dir/{file.ignore,file.txt}
>> hilco@centaur ~/tmp/repo repo (master *%)$ git status
>> # On branch master
>> # Changes not staged for commit:
>> #   (use "git add <file>..." to update what will be committed)
>> #   (use "git checkout -- <file>..." to discard changes in working directory)
>> #
>> #       modified:   src/code.txt
>> #
>> # Untracked files:
>> #   (use "git add <file>..." to include in what will be committed)
>> #
>> #       file-a.ignore
>> #       ignore-dir/
>> #       src/file-b.ignore
>          ^^^^^^^^^^^^^^^^^
> Why are these entries here?

My bad. I had a script that ran the commands but I decided to try run
them on the CL so I copy-pasted them. That changed the tabs to spaces
and ruined .gitignore.

>> no changes added to commit (use "git add" and/or "git commit -a")
>
> if your .gitignore file looks like this:
>
>   $ cat .gitignore
>   *.ignore
>   ignore-dir/
>
> then why are those items showing up under "Untracked files:" in the call
> to git status above?  /methinks something is wrong with your .gitignore
> file.  It doesn't matter in this case, since --all will cause stash to
> stash the untracked files regardless of whether they are ignored.
>
>> hilco@centaur ~/tmp/repo repo (master *%)$ git stash --no-keep-index --all
>> Saved working directory and index state WIP on master: 0fb4106 1
>> HEAD is now at 0fb4106 1
>> Not removing ignore-dir/
>> hilco@centaur ~/tmp/repo repo (master $%)$ git status
>> # On branch master
>> # Untracked files:
>> #   (use "git add <file>..." to include in what will be committed)
>> #
>> #       ignore-dir/
>> nothing added to commit but untracked files present (use "git add" to track)
>
> Also, in the future it would be nicer if you provided your list of
> commands separately, at the beginning, linked together with &&.
> This makes it easier to copy/paste into my terminal, rather than
> having to extract the commands out from within the body.
> Like this (slightly simplified):
>
>   git --version &&
>   git init &&
>   cat <<-\EOF >.gitignore &&
>        *.ignore
>        ignore-dir/
>        EOF
>   mkdir src &&
>   touch file.txt src/code.txt &&
>   git add . &&
>   git commit -m 'initial commit' &&
>   touch file-a.ignore src/file-b.ignore &&
>   echo "hello" >src/code.txt &&
>   mkdir ignore-dir &&
>   touch ignore-dir/{file.ignore,file.txt} &&
>   git status &&
>   git stash --all &&
>   git status || echo 'FAILURE'

Noted. Will do.

>> So it quite explicitly states "Not removing ignore-dir/".
>
> That message is from git-clean, and it is the real problem.
>
>> How do I
>> make sure it also stashes the ignore-dir directory?
>
> It actually did stash the ignore-dir, it just didn't remove it from
> the working directory at the end.  Try deleting the ignore-dir by
> hand and then applying the stash, ignore-dir and its content should
> be recreated.
>
> Something like this is probably the appropriate fix:
>
> diff --git a/git-stash.sh b/git-stash.sh
> index f4e6f05..a2d4b4d 100755
> --- a/git-stash.sh
> +++ b/git-stash.sh
> @@ -240,7 +240,7 @@ save_stash () {
>                test "$untracked" = "all" && CLEAN_X_OPTION=-x || CLEAN_X_OPTION
>                if test -n "$untracked"
>                then
> -                       git clean --force --quiet $CLEAN_X_OPTION
> +                       git clean --force --quiet -d $CLEAN_X_OPTION
>                fi
>
>                if test "$keep_index" = "t" && test -n $i_tree
>
> Needs tests.

I just tried it with the extra -d and it all seems to work
beautifully. Should your patch be sent anywhere?

^ 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