Re: `git stash pop` UX Problem

2014-03-01 Thread Stephen Leake
Matthieu Moy matthieu@grenoble-inp.fr writes:

 Stephen Leake stephen_le...@stephe-leake.org writes:

 So a message merge complete; you can drop the stash would be the most
 git should do.

 From the user experience point of view, that would be good. It could
 bother some users, but we have advice.* to silent this kind of warnings.

 snip explanation of implementation issues

 So, I wouldn't object, but I don't think the implementation cost is
 worth the benefit.

Ok, that makes sense.

-- 
-- Stephe
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: `git stash pop` UX Problem

2014-03-01 Thread Stephen Leake
Junio C Hamano gits...@pobox.com writes:

 Stephen Leake stephen_le...@stephe-leake.org writes:

 Matthieu Moy matthieu@grenoble-inp.fr writes:

 li...@haller-berlin.de (Stefan Haller) writes:

 Your intention was clearly to drop the stash, it just wasn't dropped
 because of the conflict. Dropping it automatically once the conflict
 is resolved would be nice.

 Your intention when you ran git stash pop, yes. Your intention when
 you ran git add, I call that guessing.

 You might be adding other files for other reasons. But if you add a file
 that does resolve a conflict caused by 'git stash pop', it is not
 guessing.

 The only thing you know for sure is that the user has consumed _one_
 part of the stashed change, no?  What if the stash had changes for
 more than one path?

Count the unmerged paths in the index; when the count is zero, all
conflicts are resolved.

paths in the stash that had no conflicts are already in the index.

So _if_ there is nothing going on except finishing the stash pop, an
unmerged path count of zero means you are done with the stash, and it
can be dropped.

 At the time of git add $path, can you reliably tell if the
 conflict to the $path the user is resolving came from a previous
 git stash pop, not from any other mergy operations, e.g. git
 stash apply or git apply -3?

This is the real problem. I can impose a rule on my team of don't do
more than one merge at a time by implementing that in the front-end,
but git can't assume that.

-- 
-- Stephe
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Replace memcpy with hashcpy when dealing hash copy globally

2014-03-01 Thread Tay Ray Chuan
On Sat, Mar 1, 2014 at 10:58 AM, Duy Nguyen pclo...@gmail.com wrote:
 On Sat, Mar 1, 2014 at 8:07 AM, Sun He sunheeh...@gmail.com wrote:
 Signed-off-by: Sun He sunheeh...@gmail.com
 ---
  Find the potential places with memcpy by the bash command:
$ find . | xargs grep memcpy.*\(.*20.*\)

  Helped-by: Michael Haggertymhag...@alum.mit.edu

 You may want to put this Helped-by before --- because it's supposed
 to end up in the final commit.

To elaborate further: anything below the three-dash is ignored when
the patch is applied. So it doesn't show up in the commit at all. I
don't really know the reason for this - probably a patch (1) thing.

You could put the patch the Helped-by before your Signed-off-by
(sometimes referred to as S-o-b).

-- 
Cheers,
Ray Chuan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: t9200 cvsexportcommit test fails on Ubuntu server 12.04.4 LTS

2014-03-01 Thread Fabio D'Alfonso

Hi,
thanks for the suggestion.

Tests failed because the cvs is built with denied root commit on 12.04, 
I did not notice as the 11.04 works. I use root for system activities on 
servers. Will sometime in the future start to sudoku...


Made a check as git user and was fine.

Fabio D'Alfonso
'Enabling Business Through IT'
cell.  +39.348.059.40.22 ***
web: www.fabiodalfonso.com http://www.fabiodalfonso.com/
email: fabio.dalfo...@fabiodalfonso.com
mailto:fabio.dalfo...@fabiodalfonso.comlinkedin: 
www.linkedin.com/in/fabiodalfonso http://it.linkedin.com/in/fabiodalfonso
twitter: www.twitter.com/#!/fabio_dalfonso 
http://www.twitter.com/#%21/fabio_dalfonso


fax: +39.06.874.599.581
BlackBerry® Wireless Enabled Address.


 ** Hidden  numbers are automatically rejected by the phone*

On 3/1/2014 7:46 AM, Jeff King wrote:

On Fri, Feb 28, 2014 at 07:45:07PM +0100, Fabio D'Alfonso wrote:


I get 12 of 15 tests faling.

Any idea? the same build works fine on 11.04 where I have a desktop version.

No clue. It works fine for me here (Debian sid). Perhaps try running the
script like:

 ./t9200-git-cvsexportcommit.sh -v -i

which should give more information about what exactly is failing?

-Peff


--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 0/3] Make git more user-friendly during a merge conflict

2014-03-01 Thread Stephen Leake
David Kastrup d...@gnu.org writes:

 Stephen Leake stephen_le...@stephe-leake.org writes:

 David Kastrup d...@gnu.org writes:

 Stephen Leake stephen_le...@stephe-leake.org writes:

 David Kastrup d...@gnu.org writes:

 do the right thing commands also tend to do the wrong thing
 occasionally with potentially disastrous results when they are used
 in scripts where the followup actions rely on the actual result.

 That is bad, and should not be allowed. On the other hand, I have yet
 to see an actual use case of bad behavior in this discussion.

 Huh.

 http://permalink.gmane.org/gmane.comp.version-control.git/242744

 That's about backward incompatibility, which is bad, but not what I was
 talking about above.

 No, it isn't.  I quote:

 I sometimes run git reset during a merge to only reset the index
 and then examine the changes introduced by the merge. With your
 changes, someone doing so would abort the merge and discard the
 merge resolution.  I very rarely do this, but even rarely, I
 wouldn't like Git to start droping data silently for me ;-).

 You should not make statements like I have yet to see an actual use
 case of bad behavior in this discussion when you actually mean I have
 not yet seen anything I would be interested in doing myself.

Clearly I misunderstood your point. Merely repeating the same statement
that I misunderstood, and adding a misunderstanding of what I said, is
not helpful.

So let me see if I can expand on your use case:

- you do 'git merge', which results in conflicts

- you edit some workspace files to resolve some of those conflicts 

(I added this step later, since it was implied but not explicit)

- you do 'git reset', intending 'git reset --mixed' (because that is the
  current default)

Actually, I can't find a precise definition of 'git reset'. Here is
the synopsis from the man page for 'git-reset' (from git 1.7.9):

   git reset [-q] [commit] [--] paths...
   git reset (--patch | -p) [commit] [--] [paths...]
   git reset (--soft | --mixed | --hard | --merge | --keep) [-q] [commit]

In 'git reset', there is no path, so it must be the second or third
form. But those _require_ one of the -- options. So 'git reset' is
illegal. Clearly something is wrong here; apparently the third line
should be:

   git reset [--soft | --mixed | --hard | --merge | --keep] [-q] [commit]

with '--mixed' as the default, as is stated later. (perhaps the
original intent was to not have a default for the third form, but
that got changed sometime?).

This command resets the index but not the working tree. I'm not
clear what reset the index means here; does it mean remove all
entries from the index, or reset the index to some previous
state? In other man pages, reset can have either meaning
depending on context.

- then you examine changes introduced by the merge. I don't know what
  this means in detail. 

Before resetting the index, you could diff a workspace file against
either HEAD or index. Now you can only diff against HEAD, so I don't
understand why you wanted to reset the index. That's not relevant to
this use case; I'll just accept that resetting the index is a useful
thing to do here. But I would like to understand why.

- with the do the right thing patch, 'git reset' does 'git reset
  --merge' instead

That Resets the index and updates the files in the working tree
that are different between commit and HEAD. 

commit in this case defaults to HEAD, so the working tree is
not changed.

So as I understand it, this does _not_ lose your conflict resolutions.

In fact, it now seems that 'git reset --mixed' is always the same as
'git reset --merge'. So I must be missing something!

-- 
-- Stephe
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: RFC GSoC idea: new git config features

2014-03-01 Thread Matthieu Moy
Jeff King p...@peff.net writes:

 If we had the keys in-memory, we could reverse this: config code asks
 for keys it cares about, and we can do an optimized lookup (binary
 search, hash, etc).

I'm actually dreaming of a system where a configuration variable could
be declared in Git's source code, with associated type (list/single
value, boolean/string/path/...), default value and documentation (and
then Documentation/config.txt could become a generated file). One could
imagine a lot of possibilities like

$ git config --describe some-variable
Type: boolean
Default value: true
Description: ...

Somehow, do for config variables what has been done for command-line
option parsing.

Migrating the whole code to such system would take time, but creating
the system and applying it to a few examples might be feasible as a GSoC
project.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] rewrite finish_bulk_checkin() using strbuf

2014-03-01 Thread He Sun
2014-03-01 15:18 GMT+08:00 Faiz Kothari faiz.of...@gmail.com:
 Hi,
 Yup, at that position.
 I don't know, but it failed a few tests on my machine related to bitmap.
 Another thing to use would be strbuf_splice()

Eric Sunshinesunsh...@sunshineco.com has came up with a more
elegant way to finish this task. That's using strbuf_setlen() instead of
strbuf_remove(). Because of the unstable network of this afternoon. The
former email is sent without the above information.
Sorry about it.

I find out that you didn't attach strbuf_remove() in your finish_bulk_checkin().
That may cause problems not only related to bitmap, because the input
packname is different from the output packname..

Cheers,
He Sun

 Anyways, no worries :)

 Cheers,
 Faiz

 On Sat, Mar 1, 2014 at 12:40 PM, He Sun sunheeh...@gmail.com wrote:
 2014-03-01 14:46 GMT+08:00 Faiz Kothari faiz.of...@gmail.com:
 From: Faiz Kotahri faiz.of...@gmail.com

 Signed-off-by: Faiz Kothari faiz.of...@gmail.com
 ---
 Sticking with implementation involving changing the prototype for
 pack-write.c:finish_tmp_packfile()
 Fixing a small bug in Sun He's implementation which caused a fail in some 
 tests.

  builtin/pack-objects.c |   25 -
  bulk-checkin.c |9 ++---
  pack-write.c   |   19 ++-
  pack.h |3 ++-
  4 files changed, 30 insertions(+), 26 deletions(-)

 diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
 index c733379..4b59bba 100644
 --- a/builtin/pack-objects.c
 +++ b/builtin/pack-objects.c
 @@ -20,6 +20,7 @@
  #include streaming.h
  #include thread-utils.h
  #include pack-bitmap.h
 +#include strbuf.h

  static const char *pack_usage[] = {
 N_(git pack-objects --stdout [options...] [ ref-list |  
 object-list]),
 @@ -803,8 +804,8 @@ static void write_pack_file(void)

 if (!pack_to_stdout) {
 struct stat st;
 -   char tmpname[PATH_MAX];
 -
 +   struct strbuf tmpname = STRBUF_INIT;
 +   int ini_length;
 /*
  * Packs are runtime accessed in their mtime
  * order since newer packs are more likely to 
 contain
 @@ -823,26 +824,24 @@ static void write_pack_file(void)
 utb.modtime = --last_mtime;
 if (utime(pack_tmp_name, utb)  0)
 warning(failed utime() on %s: %s,
 -   tmpname, strerror(errno));
 +   pack_tmp_name, 
 strerror(errno));
 }

 -   /* Enough space for -sha-1.pack? */
 -   if (sizeof(tmpname) = strlen(base_name) + 50)
 -   die(pack base name '%s' too long, 
 base_name);
 -   snprintf(tmpname, sizeof(tmpname), %s-, 
 base_name);
 +   strbuf_addf(tmpname, %s-, base_name);
 +   ini_length = tmpname.len;

 if (write_bitmap_index) {
 bitmap_writer_set_checksum(sha1);
 
 bitmap_writer_build_type_index(written_list, nr_written);
 }
 -
 -   finish_tmp_packfile(tmpname, pack_tmp_name,
 +
 +   finish_tmp_packfile(tmpname, pack_tmp_name,
 written_list, nr_written,
 pack_idx_opts, sha1);

 if (write_bitmap_index) {
 -   char *end_of_name_prefix = strrchr(tmpname, 
 0);
 -   sprintf(end_of_name_prefix, %s.bitmap, 
 sha1_to_hex(sha1));
 +   strbuf_remove(tmpname, ini_length, 
 tmpname.len - ini_length);

 Is this the position where you think may import bugs?
 I think it should be the duty of finish_tmp_packfile to ensure that the 
 tmpname
 is the same as it is input as a param.
 And in my original code, I have used strbuf_remove() at the end of
 finish_tmp_packfile.
 There is a more elegant way to finish this task.[According to ]


 +   strbuf_addf(tmpname, %s.bitmap, 
 sha1_to_hex(sha1));

 stop_progress(progress_state);

 @@ -851,10 +850,10 @@ static void write_pack_file(void)
 
 bitmap_writer_select_commits(indexed_commits, indexed_commits_nr, -1);
 bitmap_writer_build(to_pack);
 bitmap_writer_finish(written_list, 
 nr_written,
 -tmpname, 
 write_bitmap_options);
 +tmpname.buf, 
 write_bitmap_options);
 write_bitmap_index = 0;
 

Re: [PATCH] rewrite finish_bulk_checkin() using strbuf

2014-03-01 Thread Faiz Kothari
On Sat, Mar 1, 2014 at 4:33 PM, He Sun sunheeh...@gmail.com wrote:
 2014-03-01 15:18 GMT+08:00 Faiz Kothari faiz.of...@gmail.com:
 Hi,
 Yup, at that position.
 I don't know, but it failed a few tests on my machine related to bitmap.
 Another thing to use would be strbuf_splice()

 Eric Sunshinesunsh...@sunshineco.com has came up with a more
 elegant way to finish this task. That's using strbuf_setlen() instead of
 strbuf_remove(). Because of the unstable network of this afternoon. The
 former email is sent without the above information.
 Sorry about it.
You mean first use strbuf_setlen() to reduce len and then add .whatever to it?
strbuf_splice can do strbuf_remove() and add string in one shot as per the doc.
If using strbuf_setlen() is still better, I'll implement using that :)

 I find out that you didn't attach strbuf_remove() in your 
 finish_bulk_checkin().
 That may cause problems not only related to bitmap, because the input
 packname is different from the output packname..

I am not sure how that is causing the problem, because tests run just fine.
I'll still look into it. Thanks for pointing that out :)

Cheers,
Faiz
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] implemented strbuf_write_or_die()

2014-03-01 Thread Faiz Kothari
Signed-off-by: Faiz Kothari faiz.of...@gmail.com
---
Implemented write_or_die.c:strbuf_write_or_die() and used in relevant places
to substitute write_or_die(). I spotted other places where strbuf can be used
in place of buf[MAX_PATH] but that would require a change in prototype of a 
lot of functions and functions calling them and so on
I'll look for more places where strbuf can be used safely.

Thanks.

 builtin/cat-file.c |2 +-
 builtin/notes.c|4 ++--
 builtin/receive-pack.c |2 +-
 builtin/send-pack.c|2 +-
 builtin/stripspace.c   |2 +-
 builtin/tag.c  |2 +-
 bundle.c   |2 +-
 cache.h|1 +
 credential-store.c |2 +-
 fetch-pack.c   |2 +-
 http-backend.c |2 +-
 remote-curl.c  |8 +---
 write_or_die.c |9 +
 13 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index d5a93e0..c756cd5 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -255,7 +255,7 @@ static int batch_one_object(const char *obj_name, struct 
batch_options *opt,
 
strbuf_expand(buf, opt-format, expand_format, data);
strbuf_addch(buf, '\n');
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(1, buf);
strbuf_release(buf);
 
if (opt-print_contents) {
diff --git a/builtin/notes.c b/builtin/notes.c
index 2b24d05..ef40183 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -140,7 +140,7 @@ static void write_commented_object(int fd, const unsigned 
char *object)
if (strbuf_read(buf, show.out, 0)  0)
die_errno(_(could not read 'show' output));
strbuf_add_commented_lines(cbuf, buf.buf, buf.len);
-   write_or_die(fd, cbuf.buf, cbuf.len);
+   strbuf_write_or_die(fd, cbuf);
 
strbuf_release(cbuf);
strbuf_release(buf);
@@ -174,7 +174,7 @@ static void create_note(const unsigned char *object, struct 
msg_arg *msg,
strbuf_addch(buf, '\n');
strbuf_add_commented_lines(buf, note_template, 
strlen(note_template));
strbuf_addch(buf, '\n');
-   write_or_die(fd, buf.buf, buf.len);
+   strbuf_write_or_die(fd, buf);
 
write_commented_object(fd, object);
 
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 85bba35..9434516 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1114,7 +1114,7 @@ static void report(struct command *commands, const char 
*unpack_status)
if (use_sideband)
send_sideband(1, 1, buf.buf, buf.len, use_sideband);
else
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(1, buf);
strbuf_release(buf);
 }
 
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index f420b74..d053f0a 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -86,7 +86,7 @@ static void print_helper_status(struct ref *ref)
}
strbuf_addch(buf, '\n');
 
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(1, buf);
}
strbuf_release(buf);
 }
diff --git a/builtin/stripspace.c b/builtin/stripspace.c
index 1259ed7..cf5c876 100644
--- a/builtin/stripspace.c
+++ b/builtin/stripspace.c
@@ -115,7 +115,7 @@ int cmd_stripspace(int argc, const char **argv, const char 
*prefix)
else
comment_lines(buf);
 
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(1, buf);
strbuf_release(buf);
return 0;
 }
diff --git a/builtin/tag.c b/builtin/tag.c
index 74d3780..5af6ea3 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -349,7 +349,7 @@ static void create_tag(const unsigned char *object, const 
char *tag,
strbuf_commented_addf(buf, _(tag_template), 
comment_line_char);
else
strbuf_commented_addf(buf, 
_(tag_template_nocleanup), comment_line_char);
-   write_or_die(fd, buf.buf, buf.len);
+   strbuf_write_or_die(fd, buf);
strbuf_release(buf);
}
close(fd);
diff --git a/bundle.c b/bundle.c
index e99065c..435505d 100644
--- a/bundle.c
+++ b/bundle.c
@@ -279,7 +279,7 @@ int create_bundle(struct bundle_header *header, const char 
*path,
while (strbuf_getwholeline(buf, rls_fout, '\n') != EOF) {
unsigned char sha1[20];
if (buf.len  0  buf.buf[0] == '-') {
-   write_or_die(bundle_fd, buf.buf, buf.len);
+   strbuf_write_or_die(bundle_fd, buf);
if (!get_sha1_hex(buf.buf + 1, sha1)) {
struct object *object = 
parse_object_or_die(sha1, buf.buf);
object-flags |= UNINTERESTING;
diff --git a/cache.h b/cache.h
index 

Re: An idea for git bisect and a GSoC enquiry

2014-03-01 Thread Jacopo Notarstefano
 I am not sure I understand what you are trying to say.  Are you
 saying that we should stick to good/bad and allow the users use
 nothing else, because allowing fixed will be confusing?


No! Pretty much the opposite of that. My idea (the mark subcommand)
is to let people define their own pairs of labels to represent two
opposite states of a commit. My point was that, if people choose pairs
of words that are not opposites (such as good and fixed) then it's
their error, not something that git should attempt to fix or detect.

 For a young tool or a feature, catering to perfect human perfectly
 is a good first goal---if it does not work well even for error-free
 human input, it would be worthless.  However, its second goal after
 achieving that first goal ought to be to help imperfect humans.


Loved this.

 Why do you think there is nothing it can do to help the user?  Upon
 seeing bad, the tool should at least be able to say Excuse me,
 but you earlier said 'fixed' for one of the commits, so your
 vocabulary now is limited to 'fixed' and 'broken'.  I think it also
 should be able to add Did you mean to say 'broken'?, or even I'd
 assume that you meant 'broken' and will continue.


I haven't said this, but this is pretty much what I had in mind.
Suppose a user wants to find a bugfix between HEAD and HEAD~10, this
is what she would do:

$ git bisect start
$ git bisect mark working HEAD
$ git bisect mark broken HEAD~10

[git will now start bisecting as usual. Suppose that she is now at HEAD~5]

$ git bisect mark bad
- Error: unrecognized label 'bad'. You previously used 'working' and
'fixed' to describe commits in this git bisect session. Please mark
commits with one of these labels.

I suppose that we could cater a little better to imperfect humans if
we had two predefined parallel list of antonyms in which to search for
given labels and infer whether they are positive or negative labels,
but this is beyond the scope of my proposal.

 I have always wondered if we can introduce a value neutral synonyms
 to good and bad.  For a bisect session, we care only about two
 states: still-X and no-longer-X where X may be 'working' for the
 normal bug-hunting bisection and 'broken' for the fix-hunting one.

 $ git bisect still-working v1.6.0
 $ git bisect no-longer-working v1.8.0

 would be a way to find a bug that was introduced during v1.6.0..v1.8.0,
 while

 $ git bisect still-broken v1.6.0
 $ git bisect no-longer-broken v1.8.0

 would be a way to find a fix in the same range.  The lowest-level
 bisection machinery could just _ignore_ anything after still/no-longer
 and do its thing, [...]

This is remarkably similar to my proposal. Using mark, these would be:

$ git bisect mark working v1.6.0
$ git bisect mark not-working v1.8.0

and

$ git bisect mark broken v1.6.0
$ git bisect mark not-broken v1.8.0

 while the end-user facing layer could enforce,
 once one commit is marked as still-X (or no-longer-X), that nothing
 other than the same X is used, and issue an error message, perhaps
 like this:

 $ git bisect still-broken v1.6.0
 $ git bisect still-working v1.8.0
 error: You earlier marked v1.6.0 as still-broken and
 error: are hunting for the first commit that can be marked
 error: as no-longer-broken.  Say either still-broken or
 error: no-longer-broken, not still-working.

 and that can be done without having to understand that broken is
 the opposite of working (of course if we understood that, we could
 even offer to guess that the user meant no-longer-broken by
 still-working, but we do not want to go there).

Here my proposal differs in that I have no way of knowing which label
is good and which label is bad: I blindly accept two distinct labels
and bisect with those. I gave an example of this behaviour above.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 0/3] Make git more user-friendly during a merge conflict

2014-03-01 Thread Matthieu Moy
Stephen Leake stephen_le...@stephe-leake.org writes:

 So as I understand it, this does _not_ lose your conflict resolutions.

Well, then maybe it's time to try the command before continuing
commenting on its behavior ;-).

$ git status
[...]
both modified:  foo.txt
[...]
$ git diff
diff --cc foo.txt
index 595f399,996c0e1..000
--- a/foo.txt
+++ b/foo.txt
@@@ -1,1 -1,1 +1,1 @@@
- content1
 -content2
++resolved
$ git reset --merge
$ git status
On branch master
nothing to commit, working directory clean
$

 In fact, it now seems that 'git reset --mixed' is always the same as
 'git reset --merge'. So I must be missing something!

git reset --merge is an alias for git merge --abort (IIRC, it's
actually the other way around). Essentially, it reverts, or tries to
revert everything (worktree and index) as it was before the merge. That
includes throwing away conflict resolution.

Now, I do agree that the documentation of git reset is terrible, and I
actually think that the command does too many different things (putting
git reset and git reset --hard so close to each other is not a good
idead IMHO: the first is a harmless command I use very often, and the
second is one of the most destructive operation Git has).

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] branch: die when setting branch as own upstream

2014-03-01 Thread Brian Gesiak
From: modocache modoca...@gmail.com

Branch set as own upstream using one of the following commands returns
immediately with an exit code of 0:

- `git branch --set-upstream-to foo refs/heads/foo`
- `git branch --force --track foo foo`

Since neither of these actions currently set the upstream, an exit code
of 0 is misleading. Instead, exit with a status code indicating failure
by using the die function.

Signed-off-by: Brian Gesiak modoca...@gmail.com
---
 branch.c  | 9 ++---
 t/t3200-branch.sh | 6 +++---
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/branch.c b/branch.c
index e163f3c..9bac8b5 100644
--- a/branch.c
+++ b/branch.c
@@ -54,13 +54,8 @@ void install_branch_config(int flag, const char *local, 
const char *origin, cons
struct strbuf key = STRBUF_INIT;
int rebasing = should_setup_rebase(origin);
 
-   if (shortname
-!strcmp(local, shortname)
-!origin) {
-   warning(_(Not setting branch %s as its own upstream.),
-   local);
-   return;
-   }
+   if (shortname  !strcmp(local, shortname)  !origin)
+   die(_(Not setting branch %s as its own upstream.), local);
 
strbuf_addf(key, branch.%s.remote, local);
git_config_set(key.buf, origin ? origin : .);
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 6164126..3ac493f 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -507,10 +507,10 @@ EOF
test_cmp expected actual
 '
 
-test_expect_success '--set-upstream-to shows warning if used to set branch as 
own upstream' '
-   git branch --set-upstream-to refs/heads/my13 my13 2actual 
+test_expect_success '--set-upstream-to fails if used to set branch as own 
upstream' '
+   test_must_fail git branch --set-upstream-to refs/heads/my13 my13 
2actual 
cat expected EOF 
-warning: Not setting branch my13 as its own upstream.
+fatal: Not setting branch my13 as its own upstream.
 EOF
test_i18ncmp expected actual
 '
-- 
1.8.3.4 (Apple Git-47)

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 00/27] Support multiple checkouts

2014-03-01 Thread Nguyễn Thái Ngọc Duy
Phew.. v4 changes are

- address all comments from Junio and Eric (I hope)
- fix git checkout --to not working from the linked checkouts
- report unused files (e.g. $GIT_DIR/repos/xx/config) in count-objects -v

Nguyễn Thái Ngọc Duy (27):
  path.c: make get_pathname() return strbuf instead of static buffer
  Convert git_snpath() to strbuf_git_path()
  path.c: rename vsnpath() to do_git_path()
  path.c: group git_path(), git_pathdup() and strbuf_git_path() together
  Make git_path() aware of file relocation in $GIT_DIR
  *.sh: respect $GIT_INDEX_FILE
  reflog: avoid constructing .lock path with git_path
  fast-import: use git_path() for accessing .git dir instead of get_git_dir()
  commit: use SEQ_DIR instead of hardcoding sequencer
  Add new environment variable $GIT_COMMON_DIR
  git-sh-setup.sh: use rev-parse --git-path to get $GIT_DIR/objects
  *.sh: avoid hardcoding $GIT_DIR/hooks/...
  git-stash: avoid hardcoding $GIT_DIR/logs/
  setup.c: convert is_git_directory() to use strbuf
  setup.c: detect $GIT_COMMON_DIR in is_git_directory()
  setup.c: convert check_repository_format_gently to use strbuf
  setup.c: detect $GIT_COMMON_DIR check_repository_format_gently()
  setup.c: support multi-checkout repo setup
  wrapper.c: wrapper to open a file, fprintf then close
  use new wrapper write_file() for simple file writing
  checkout: support checking out into a new working directory
  checkout: clean up half-prepared directories in --to mode
  checkout: detach if the branch is already checked out elsewhere
  prune: strategies for linked checkouts
  gc: style change -- no SP before closing bracket
  gc: support prune --repos
  count-objects: report unused files in $GIT_DIR/repos/...

 Documentation/config.txt   |   8 +
 Documentation/git-checkout.txt |  34 
 Documentation/git-prune.txt|   3 +
 Documentation/git-rev-parse.txt|   8 +
 Documentation/git.txt  |   9 ++
 Documentation/gitrepository-layout.txt |  75 +++--
 builtin/branch.c   |   4 +-
 builtin/checkout.c | 274 +++--
 builtin/commit.c   |   2 +-
 builtin/count-objects.c|  37 -
 builtin/gc.c   |  21 ++-
 builtin/init-db.c  |   7 +-
 builtin/prune.c|  74 +
 builtin/reflog.c   |   2 +-
 builtin/rev-parse.c|  11 ++
 cache.h|  10 +-
 compat/mingw.h |   1 +
 daemon.c   |  11 +-
 environment.c  |  24 ++-
 fast-import.c  |   5 +-
 git-am.sh  |  22 +--
 git-compat-util.h  |   4 +
 git-pull.sh|   2 +-
 git-rebase--interactive.sh |   6 +-
 git-rebase--merge.sh   |   6 +-
 git-rebase.sh  |   4 +-
 git-sh-setup.sh|   2 +-
 git-stash.sh   |   6 +-
 path.c | 206 -
 refs.c |  66 +---
 refs.h |   2 +-
 setup.c| 124 +++
 submodule.c|   9 +-
 t/t0060-path-utils.sh  |  34 
 t/t1501-worktree.sh|  76 +
 t/t1510-repo-setup.sh  |   1 +
 t/t2025-checkout-to.sh (new +x)|  57 +++
 templates/hooks--applypatch-msg.sample |   4 +-
 templates/hooks--pre-applypatch.sample |   4 +-
 trace.c|   1 +
 transport.c|   8 +-
 wrapper.c  |  31 
 42 files changed, 1069 insertions(+), 226 deletions(-)

-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 03/27] path.c: rename vsnpath() to do_git_path()

2014-03-01 Thread Nguyễn Thái Ngọc Duy
The name vsnpath() gives an impression that this is general path
handling function. It's not. This is the underlying implementation of
git_path(), git_pathdup() and strbuf_git_path() which will prefix
$GIT_DIR in the result string.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 path.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/path.c b/path.c
index b52a16f..29048fe 100644
--- a/path.c
+++ b/path.c
@@ -60,7 +60,7 @@ char *mksnpath(char *buf, size_t n, const char *fmt, ...)
return cleanup_path(buf);
 }
 
-static void vsnpath(struct strbuf *buf, const char *fmt, va_list args)
+static void do_git_path(struct strbuf *buf, const char *fmt, va_list args)
 {
const char *git_dir = get_git_dir();
strbuf_addstr(buf, git_dir);
@@ -74,7 +74,7 @@ void strbuf_git_path(struct strbuf *sb, const char *fmt, ...)
 {
va_list args;
va_start(args, fmt);
-   vsnpath(sb, fmt, args);
+   do_git_path(sb, fmt, args);
va_end(args);
 }
 
@@ -83,7 +83,7 @@ char *git_pathdup(const char *fmt, ...)
struct strbuf path = STRBUF_INIT;
va_list args;
va_start(args, fmt);
-   vsnpath(path, fmt, args);
+   do_git_path(path, fmt, args);
va_end(args);
return strbuf_detach(path, NULL);
 }
@@ -114,7 +114,7 @@ char *git_path(const char *fmt, ...)
struct strbuf *pathname = get_pathname();
va_list args;
va_start(args, fmt);
-   vsnpath(pathname, fmt, args);
+   do_git_path(pathname, fmt, args);
va_end(args);
return pathname-buf;
 }
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 02/27] Convert git_snpath() to strbuf_git_path()

2014-03-01 Thread Nguyễn Thái Ngọc Duy
In the previous patch, git_snpath() is modified to allocate a new
strbuf buffer because vsnpath() needs that. But that makes it awkward
because git_snpath() receives a pre-allocated buffer from outside and
has to copy data back. Rename it to strbuf_git_path() and make it
receive strbuf directly.

The conversion from git_snpath() to git_path() in
update_refs_for_switch() is safe because that function does not keep
any pointer to the round-robin buffer pool allocated by
get_pathname().

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/checkout.c | 22 +-
 cache.h|  4 ++--
 path.c | 11 ++---
 refs.c | 66 +++---
 refs.h |  2 +-
 5 files changed, 58 insertions(+), 47 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 5df3837..0570e41 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -585,18 +585,20 @@ static void update_refs_for_switch(const struct 
checkout_opts *opts,
if (opts-new_orphan_branch) {
if (opts-new_branch_log  !log_all_ref_updates) {
int temp;
-   char log_file[PATH_MAX];
+   struct strbuf log_file = STRBUF_INIT;
char *ref_name = mkpath(refs/heads/%s, 
opts-new_orphan_branch);
+   int ret;
 
temp = log_all_ref_updates;
log_all_ref_updates = 1;
-   if (log_ref_setup(ref_name, log_file, 
sizeof(log_file))) {
+   ret = log_ref_setup(ref_name, log_file);
+   log_all_ref_updates = temp;
+   strbuf_release(log_file);
+   if (ret) {
fprintf(stderr, _(Can not do reflog 
for '%s'\n),
opts-new_orphan_branch);
-   log_all_ref_updates = temp;
return;
}
-   log_all_ref_updates = temp;
}
}
else
@@ -651,14 +653,10 @@ static void update_refs_for_switch(const struct 
checkout_opts *opts,
new-name);
}
}
-   if (old-path  old-name) {
-   char log_file[PATH_MAX], ref_file[PATH_MAX];
-
-   git_snpath(log_file, sizeof(log_file), logs/%s, 
old-path);
-   git_snpath(ref_file, sizeof(ref_file), %s, old-path);
-   if (!file_exists(ref_file)  file_exists(log_file))
-   remove_path(log_file);
-   }
+   if (old-path  old-name 
+   !file_exists(git_path(%s, old-path)) 
+file_exists(git_path(logs/%s, old-path)))
+   remove_path(git_path(logs/%s, old-path));
}
remove_branch_state();
strbuf_release(msg);
diff --git a/cache.h b/cache.h
index dc040fb..8d3697e 100644
--- a/cache.h
+++ b/cache.h
@@ -646,8 +646,8 @@ extern int check_repository_format(void);
 
 extern char *mksnpath(char *buf, size_t n, const char *fmt, ...)
__attribute__((format (printf, 3, 4)));
-extern char *git_snpath(char *buf, size_t n, const char *fmt, ...)
-   __attribute__((format (printf, 3, 4)));
+extern void strbuf_git_path(struct strbuf *sb, const char *fmt, ...)
+   __attribute__((format (printf, 2, 3)));
 extern char *git_pathdup(const char *fmt, ...)
__attribute__((format (printf, 1, 2)));
 extern char *mkpathdup(const char *fmt, ...)
diff --git a/path.c b/path.c
index 5346700..b52a16f 100644
--- a/path.c
+++ b/path.c
@@ -70,19 +70,12 @@ static void vsnpath(struct strbuf *buf, const char *fmt, 
va_list args)
strbuf_cleanup_path(buf);
 }
 
-char *git_snpath(char *buf, size_t n, const char *fmt, ...)
+void strbuf_git_path(struct strbuf *sb, const char *fmt, ...)
 {
-   struct strbuf sb = STRBUF_INIT;
va_list args;
va_start(args, fmt);
-   vsnpath(sb, fmt, args);
+   vsnpath(sb, fmt, args);
va_end(args);
-   if (sb.len = n)
-   strlcpy(buf, bad_path, n);
-   else
-   memcpy(buf, sb.buf, sb.len + 1);
-   strbuf_release(sb);
-   return buf;
 }
 
 char *git_pathdup(const char *fmt, ...)
diff --git a/refs.c b/refs.c
index 89228e2..434bd5e 100644
--- a/refs.c
+++ b/refs.c
@@ -1325,10 +1325,12 @@ static const char *handle_missing_loose_ref(const char 
*refname,
 
 const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int 
reading, int *flag)
 {
+   struct strbuf sb_path = STRBUF_INIT;
int depth = MAXDEPTH;

[PATCH v4 01/27] path.c: make get_pathname() return strbuf instead of static buffer

2014-03-01 Thread Nguyễn Thái Ngọc Duy
We've been avoiding PATH_MAX whenever possible. This patch makes
get_pathname() return a strbuf and updates the callers to take
advantage of this. The code is simplified as we no longer need to
worry about buffer overflow.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 path.c | 120 -
 1 file changed, 51 insertions(+), 69 deletions(-)

diff --git a/path.c b/path.c
index 24594c4..5346700 100644
--- a/path.c
+++ b/path.c
@@ -16,11 +16,15 @@ static int get_st_mode_bits(const char *path, int *mode)
 
 static char bad_path[] = /bad-path/;
 
-static char *get_pathname(void)
+static struct strbuf *get_pathname(void)
 {
-   static char pathname_array[4][PATH_MAX];
+   static struct strbuf pathname_array[4] = {
+   STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT
+   };
static int index;
-   return pathname_array[3  ++index];
+   struct strbuf *sb = pathname_array[3  ++index];
+   strbuf_reset(sb);
+   return sb;
 }
 
 static char *cleanup_path(char *path)
@@ -34,6 +38,13 @@ static char *cleanup_path(char *path)
return path;
 }
 
+static void strbuf_cleanup_path(struct strbuf *sb)
+{
+   char *path = cleanup_path(sb-buf);
+   if (path  sb-buf)
+   strbuf_remove(sb, 0, path - sb-buf);
+}
+
 char *mksnpath(char *buf, size_t n, const char *fmt, ...)
 {
va_list args;
@@ -49,85 +60,70 @@ char *mksnpath(char *buf, size_t n, const char *fmt, ...)
return cleanup_path(buf);
 }
 
-static char *vsnpath(char *buf, size_t n, const char *fmt, va_list args)
+static void vsnpath(struct strbuf *buf, const char *fmt, va_list args)
 {
const char *git_dir = get_git_dir();
-   size_t len;
-
-   len = strlen(git_dir);
-   if (n  len + 1)
-   goto bad;
-   memcpy(buf, git_dir, len);
-   if (len  !is_dir_sep(git_dir[len-1]))
-   buf[len++] = '/';
-   len += vsnprintf(buf + len, n - len, fmt, args);
-   if (len = n)
-   goto bad;
-   return cleanup_path(buf);
-bad:
-   strlcpy(buf, bad_path, n);
-   return buf;
+   strbuf_addstr(buf, git_dir);
+   if (buf-len  !is_dir_sep(buf-buf[buf-len - 1]))
+   strbuf_addch(buf, '/');
+   strbuf_vaddf(buf, fmt, args);
+   strbuf_cleanup_path(buf);
 }
 
 char *git_snpath(char *buf, size_t n, const char *fmt, ...)
 {
-   char *ret;
+   struct strbuf sb = STRBUF_INIT;
va_list args;
va_start(args, fmt);
-   ret = vsnpath(buf, n, fmt, args);
+   vsnpath(sb, fmt, args);
va_end(args);
-   return ret;
+   if (sb.len = n)
+   strlcpy(buf, bad_path, n);
+   else
+   memcpy(buf, sb.buf, sb.len + 1);
+   strbuf_release(sb);
+   return buf;
 }
 
 char *git_pathdup(const char *fmt, ...)
 {
-   char path[PATH_MAX], *ret;
+   struct strbuf path = STRBUF_INIT;
va_list args;
va_start(args, fmt);
-   ret = vsnpath(path, sizeof(path), fmt, args);
+   vsnpath(path, fmt, args);
va_end(args);
-   return xstrdup(ret);
+   return strbuf_detach(path, NULL);
 }
 
 char *mkpathdup(const char *fmt, ...)
 {
-   char *path;
struct strbuf sb = STRBUF_INIT;
va_list args;
-
va_start(args, fmt);
strbuf_vaddf(sb, fmt, args);
va_end(args);
-   path = xstrdup(cleanup_path(sb.buf));
-
-   strbuf_release(sb);
-   return path;
+   strbuf_cleanup_path(sb);
+   return strbuf_detach(sb, NULL);
 }
 
 char *mkpath(const char *fmt, ...)
 {
va_list args;
-   unsigned len;
-   char *pathname = get_pathname();
-
+   struct strbuf *pathname = get_pathname();
va_start(args, fmt);
-   len = vsnprintf(pathname, PATH_MAX, fmt, args);
+   strbuf_vaddf(pathname, fmt, args);
va_end(args);
-   if (len = PATH_MAX)
-   return bad_path;
-   return cleanup_path(pathname);
+   return cleanup_path(pathname-buf);
 }
 
 char *git_path(const char *fmt, ...)
 {
-   char *pathname = get_pathname();
+   struct strbuf *pathname = get_pathname();
va_list args;
-   char *ret;
-
va_start(args, fmt);
-   ret = vsnpath(pathname, PATH_MAX, fmt, args);
+   vsnpath(pathname, fmt, args);
va_end(args);
-   return ret;
+   return pathname-buf;
 }
 
 void home_config_paths(char **global, char **xdg, char *file)
@@ -158,41 +154,27 @@ void home_config_paths(char **global, char **xdg, char 
*file)
 
 char *git_path_submodule(const char *path, const char *fmt, ...)
 {
-   char *pathname = get_pathname();
-   struct strbuf buf = STRBUF_INIT;
+   struct strbuf *buf = get_pathname();
const char *git_dir;
va_list args;
-   unsigned len;
-
-   len = strlen(path);
-   if (len  PATH_MAX-100)
-   return bad_path;
 
-   strbuf_addstr(buf, path);
-   

[PATCH v4 09/27] commit: use SEQ_DIR instead of hardcoding sequencer

2014-03-01 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/commit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index 3767478..ee3ac10 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -155,7 +155,7 @@ static void determine_whence(struct wt_status *s)
whence = FROM_MERGE;
else if (file_exists(git_path(CHERRY_PICK_HEAD))) {
whence = FROM_CHERRY_PICK;
-   if (file_exists(git_path(sequencer)))
+   if (file_exists(git_path(SEQ_DIR)))
sequencer_in_use = 1;
}
else
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 08/27] fast-import: use git_path() for accessing .git dir instead of get_git_dir()

2014-03-01 Thread Nguyễn Thái Ngọc Duy
This allows git_path() to redirect info/fast-import to another place
if needed

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 fast-import.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/fast-import.c b/fast-import.c
index 4fd18a3..08a1e78 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -3125,12 +3125,9 @@ static void parse_progress(void)
 
 static char* make_fast_import_path(const char *path)
 {
-   struct strbuf abs_path = STRBUF_INIT;
-
if (!relative_marks_paths || is_absolute_path(path))
return xstrdup(path);
-   strbuf_addf(abs_path, %s/info/fast-import/%s, get_git_dir(), path);
-   return strbuf_detach(abs_path, NULL);
+   return xstrdup(git_path(info/fast-import/%s, path));
 }
 
 static void option_import_marks(const char *marks,
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 07/27] reflog: avoid constructing .lock path with git_path

2014-03-01 Thread Nguyễn Thái Ngọc Duy
git_path() soon understands the path given to it and can transform the
path instead of just prepending $GIT_DIR. So given path abc,
git_path() may return $GIT_DIR/abc. But given path def, git_path()
may return $GIT_DIR/ghi.

Giving path def.lock to git_path() may confuse it and make it
believe def.lock should not be transformed because the signature is
def.lock not def. But we want the lock file to have the same base
name with the locked file (e.g. ghi.lock, not def.lock). It's best
to append .lock after git_path() has done its conversion.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/reflog.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/reflog.c b/builtin/reflog.c
index 852cff6..ccf2cf6 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -372,7 +372,7 @@ static int expire_reflog(const char *ref, const unsigned 
char *sha1, int unused,
if (!file_exists(log_file))
goto finish;
if (!cmd-dry_run) {
-   newlog_path = git_pathdup(logs/%s.lock, ref);
+   newlog_path = mkpathdup(%s.lock, log_file);
cb.newlog = fopen(newlog_path, w);
}
 
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 12/27] *.sh: avoid hardcoding $GIT_DIR/hooks/...

2014-03-01 Thread Nguyễn Thái Ngọc Duy
If $GIT_COMMON_DIR is set, it should be $GIT_COMMON_DIR/hooks/, not
$GIT_DIR/hooks/. Just let rev-parse --git-path handle it.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 git-am.sh  | 22 +++---
 git-rebase--interactive.sh |  6 +++---
 git-rebase--merge.sh   |  6 ++
 git-rebase.sh  |  4 ++--
 templates/hooks--applypatch-msg.sample |  4 ++--
 templates/hooks--pre-applypatch.sample |  4 ++--
 6 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/git-am.sh b/git-am.sh
index bbea430..dfa0618 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -803,10 +803,10 @@ To restore the original branch and stop patching run 
\\$cmdline --abort\.
continue
fi
 
-   if test -x $GIT_DIR/hooks/applypatch-msg
+   hook=`git rev-parse --git-path hooks/applypatch-msg`
+   if test -x $hook
then
-   $GIT_DIR/hooks/applypatch-msg $dotest/final-commit ||
-   stop_here $this
+   $hook $dotest/final-commit || stop_here $this
fi
 
if test -f $dotest/final-commit
@@ -880,9 +880,10 @@ did you forget to use 'git add'?
stop_here_user_resolve $this
fi
 
-   if test -x $GIT_DIR/hooks/pre-applypatch
+   hook=`git rev-parse --git-path hooks/pre-applypatch`
+   if test -x $hook
then
-   $GIT_DIR/hooks/pre-applypatch || stop_here $this
+   $hook || stop_here $this
fi
 
tree=$(git write-tree) 
@@ -908,18 +909,17 @@ did you forget to use 'git add'?
echo $(cat $dotest/original-commit) $commit  
$dotest/rewritten
fi
 
-   if test -x $GIT_DIR/hooks/post-applypatch
-   then
-   $GIT_DIR/hooks/post-applypatch
-   fi
+   hook=`git rev-parse --git-path hooks/post-applypatch`
+   test -x $hook  $hook
 
go_next
 done
 
 if test -s $dotest/rewritten; then
 git notes copy --for-rewrite=rebase  $dotest/rewritten
-if test -x $GIT_DIR/hooks/post-rewrite; then
-   $GIT_DIR/hooks/post-rewrite rebase  $dotest/rewritten
+hook=`git rev-parse --git-path hooks/post-rewrite`
+if test -x $hook; then
+   $hook rebase  $dotest/rewritten
 fi
 fi
 
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 43c19e0..d741b04 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -632,9 +632,9 @@ do_next () {
git notes copy --for-rewrite=rebase  $rewritten_list ||
true # we don't care if this copying failed
} 
-   if test -x $GIT_DIR/hooks/post-rewrite 
-   test -s $rewritten_list; then
-   $GIT_DIR/hooks/post-rewrite rebase  $rewritten_list
+   hook=`git rev-parse --git-path hooks/post-rewrite`
+   if test -x $hook  test -s $rewritten_list; then
+   $hook rebase  $rewritten_list
true # we don't care if this hook failed
fi 
warn Successfully rebased and updated $head_name.
diff --git a/git-rebase--merge.sh b/git-rebase--merge.sh
index e7d96de..68f5d09 100644
--- a/git-rebase--merge.sh
+++ b/git-rebase--merge.sh
@@ -93,10 +93,8 @@ finish_rb_merge () {
if test -s $state_dir/rewritten
then
git notes copy --for-rewrite=rebase $state_dir/rewritten
-   if test -x $GIT_DIR/hooks/post-rewrite
-   then
-   $GIT_DIR/hooks/post-rewrite rebase 
$state_dir/rewritten
-   fi
+   hook=`git rev-parse --git-path hooks/post-rewrite`
+   test -x $hook  $hook rebase $state_dir/rewritten
fi
say All done.
 }
diff --git a/git-rebase.sh b/git-rebase.sh
index 8a3efa2..1cf8dba 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -195,9 +195,9 @@ run_specific_rebase () {
 
 run_pre_rebase_hook () {
if test -z $ok_to_skip_pre_rebase 
-  test -x $GIT_DIR/hooks/pre-rebase
+  test -x `git rev-parse --git-path hooks/pre-rebase`
then
-   $GIT_DIR/hooks/pre-rebase ${1+$@} ||
+   `git rev-parse --git-path hooks/pre-rebase` ${1+$@} ||
die $(gettext The pre-rebase hook refused to rebase.)
fi
 }
diff --git a/templates/hooks--applypatch-msg.sample 
b/templates/hooks--applypatch-msg.sample
index 8b2a2fe..28b843b 100755
--- a/templates/hooks--applypatch-msg.sample
+++ b/templates/hooks--applypatch-msg.sample
@@ -10,6 +10,6 @@
 # To enable this hook, rename this file to applypatch-msg.
 
 . git-sh-setup
-test -x $GIT_DIR/hooks/commit-msg 
-   exec $GIT_DIR/hooks/commit-msg ${1+$@}
+commitmsg=`git rev-parse --git-path hooks/commit-msg`
+test -x $commitmsg  exec $commitmsg ${1+$@}
 :
diff --git a/templates/hooks--pre-applypatch.sample 
b/templates/hooks--pre-applypatch.sample
index b1f187c..51aa244 100755
--- a/templates/hooks--pre-applypatch.sample
+++ 

[PATCH v4 11/27] git-sh-setup.sh: use rev-parse --git-path to get $GIT_DIR/objects

2014-03-01 Thread Nguyễn Thái Ngọc Duy
If $GIT_COMMON_DIR is set, $GIT_OBJECT_DIRECTORY should be
$GIT_COMMON_DIR/objects, not $GIT_DIR/objects. Just let rev-parse
--git-path handle it.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 git-sh-setup.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/git-sh-setup.sh b/git-sh-setup.sh
index fffa3c7..475ca43 100644
--- a/git-sh-setup.sh
+++ b/git-sh-setup.sh
@@ -343,7 +343,7 @@ then
echo 2 Unable to determine absolute path of git directory
exit 1
}
-   : ${GIT_OBJECT_DIRECTORY=$GIT_DIR/objects}
+   : ${GIT_OBJECT_DIRECTORY=$(git rev-parse --git-path objects)}
 fi
 
 peel_committish () {
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 10/27] Add new environment variable $GIT_COMMON_DIR

2014-03-01 Thread Nguyễn Thái Ngọc Duy
This variable is intended to support multiple working directories
attached to a repository. Such a repository may have a main working
directory, created by either git init or git clone and one or more
linked working directories. These working directories and the main
repository share the same repository directory.

In linked working directories, $GIT_COMMON_DIR must be defined to point
to the real repository directory and $GIT_DIR points to an unused
subdirectory inside $GIT_COMMON_DIR. File locations inside the
repository are reorganized from the linked worktree view point:

 - worktree-specific such as HEAD, logs/HEAD, index, other top-level
   refs and unrecognized files are from $GIT_DIR.

 - the rest like objects, refs, info, hooks, packed-refs, shallow...
   are from $GIT_COMMON_DIR

Scripts are supposed to retrieve paths in $GIT_DIR with git rev-parse
--git-path, which will take care of $GIT_DIR vs $GIT_COMMON_DIR
business.

The redirection is done by git_path(), git_pathdup() and
strbuf_git_path(). The selected list of paths goes to $GIT_COMMON_DIR,
not the other way around in case a developer adds a new
worktree-specific file and it's accidentally promoted to be shared
across repositories (this includes unknown files added by third party
commands)

The list of known files that belong to $GIT_DIR are:

ADD_EDIT.patch BISECT_ANCESTORS_OK BISECT_EXPECTED_REV BISECT_LOG
BISECT_NAMES CHERRY_PICK_HEAD COMMIT_MSG FETCH_HEAD HEAD MERGE_HEAD
MERGE_MODE MERGE_RR NOTES_EDITMSG NOTES_MERGE_WORKTREE ORIG_HEAD
REVERT_HEAD SQUASH_MSG TAG_EDITMSG fast_import_crash_* logs/HEAD
next-index-* rebase-apply rebase-merge rsync-refs-* sequencer/*
shallow_*

Path mapping is NOT done for git_path_submodule(). Multi-checkouts are
not supported as submodules.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/git.txt  |  8 +++
 Documentation/gitrepository-layout.txt | 42 ++
 cache.h|  4 +++-
 environment.c  | 19 +++
 path.c | 29 +++
 t/t0060-path-utils.sh  | 15 
 6 files changed, 103 insertions(+), 14 deletions(-)

diff --git a/Documentation/git.txt b/Documentation/git.txt
index 02bbc08..b094b1f 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -773,6 +773,14 @@ Git so take care if using Cogito etc.
an explicit repository directory set via 'GIT_DIR' or on the
command line.
 
+'GIT_COMMON_DIR'::
+   If this variable is set to a path, non-worktree files that are
+   normally in $GIT_DIR will be taken from this path
+   instead. Worktree-specific files such as HEAD or index are
+   taken from $GIT_DIR. See linkgit:gitrepository-layout[5] for
+   details. This variable has lower precedence than other path
+   variables such as GIT_INDEX_FILE, GIT_OBJECT_DIRECTORY...
+
 Git Commits
 ~~~
 'GIT_AUTHOR_NAME'::
diff --git a/Documentation/gitrepository-layout.txt 
b/Documentation/gitrepository-layout.txt
index aa03882..10672a1 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -46,6 +46,9 @@ of incomplete object store is not suitable to be published for
 use with dumb transports but otherwise is OK as long as
 `objects/info/alternates` points at the object stores it
 borrows from.
++
+This directory is ignored $GIT_COMMON_DIR is set and
+$GIT_COMMON_DIR/objects will be used instead.
 
 objects/[0-9a-f][0-9a-f]::
A newly created object is stored in its own file.
@@ -92,7 +95,8 @@ refs::
References are stored in subdirectories of this
directory.  The 'git prune' command knows to preserve
objects reachable from refs found in this directory and
-   its subdirectories.
+   its subdirectories. This directory is ignored $GIT_COMMON_DIR
+   is set and $GIT_COMMON_DIR/refs will be used instead.
 
 refs/heads/`name`::
records tip-of-the-tree commit objects of branch `name`
@@ -114,7 +118,8 @@ refs/replace/`obj-sha1`::
 packed-refs::
records the same information as refs/heads/, refs/tags/,
and friends record in a more efficient way.  See
-   linkgit:git-pack-refs[1].
+   linkgit:git-pack-refs[1]. This file is ignored $GIT_COMMON_DIR
+   is set and $GIT_COMMON_DIR/packed-refs will be used instead.
 
 HEAD::
A symref (see glossary) to the `refs/heads/` namespace
@@ -133,6 +138,11 @@ being a symref to point at the current branch.  Such a 
state
 is often called 'detached HEAD.'  See linkgit:git-checkout[1]
 for details.
 
+config::
+   Repository specific configuration file. This file is ignored
+   $GIT_COMMON_DIR is set and $GIT_COMMON_DIR/config will be
+   used instead.
+
 branches::
A slightly deprecated way to store shorthands to be used
to specify a URL to 'git fetch', 'git pull' and 'git push'.

[PATCH v4 13/27] git-stash: avoid hardcoding $GIT_DIR/logs/....

2014-03-01 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 git-stash.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/git-stash.sh b/git-stash.sh
index ae7d16e..12d9b37 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -183,7 +183,7 @@ store_stash () {
fi
 
# Make sure the reflog for stash is kept.
-   : $GIT_DIR/logs/$ref_stash
+   : `git rev-parse --git-path logs/$ref_stash`
git update-ref -m $stash_msg $ref_stash $w_commit
ret=$?
test $ret != 0  test -z $quiet 
@@ -258,7 +258,7 @@ save_stash () {
say $(gettext No local changes to save)
exit 0
fi
-   test -f $GIT_DIR/logs/$ref_stash ||
+   test -f `git rev-parse --git-path logs/$ref_stash` ||
clear_stash || die $(gettext Cannot initialize stash)
 
create_stash $stash_msg $untracked
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 04/27] path.c: group git_path(), git_pathdup() and strbuf_git_path() together

2014-03-01 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 path.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/path.c b/path.c
index 29048fe..ccd7228 100644
--- a/path.c
+++ b/path.c
@@ -78,6 +78,16 @@ void strbuf_git_path(struct strbuf *sb, const char *fmt, ...)
va_end(args);
 }
 
+char *git_path(const char *fmt, ...)
+{
+   struct strbuf *pathname = get_pathname();
+   va_list args;
+   va_start(args, fmt);
+   do_git_path(pathname, fmt, args);
+   va_end(args);
+   return pathname-buf;
+}
+
 char *git_pathdup(const char *fmt, ...)
 {
struct strbuf path = STRBUF_INIT;
@@ -109,16 +119,6 @@ char *mkpath(const char *fmt, ...)
return cleanup_path(pathname-buf);
 }
 
-char *git_path(const char *fmt, ...)
-{
-   struct strbuf *pathname = get_pathname();
-   va_list args;
-   va_start(args, fmt);
-   do_git_path(pathname, fmt, args);
-   va_end(args);
-   return pathname-buf;
-}
-
 void home_config_paths(char **global, char **xdg, char *file)
 {
char *xdg_home = getenv(XDG_CONFIG_HOME);
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 06/27] *.sh: respect $GIT_INDEX_FILE

2014-03-01 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 git-pull.sh  | 2 +-
 git-stash.sh | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/git-pull.sh b/git-pull.sh
index 0a5aa2c..c9dc9ba 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -218,7 +218,7 @@ test true = $rebase  {
if ! git rev-parse -q --verify HEAD /dev/null
then
# On an unborn branch
-   if test -f $GIT_DIR/index
+   if test -f `git rev-parse --git-path index`
then
die $(gettext updating an unborn branch with changes 
added to the index)
fi
diff --git a/git-stash.sh b/git-stash.sh
index f0a94ab..ae7d16e 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -20,7 +20,7 @@ require_work_tree
 cd_to_toplevel
 
 TMP=$GIT_DIR/.git-stash.$$
-TMPindex=${GIT_INDEX_FILE-$GIT_DIR/index}.stash.$$
+TMPindex=${GIT_INDEX_FILE-`git rev-parse --git-path index`}.stash.$$
 trap 'rm -f $TMP-* $TMPindex' 0
 
 ref_stash=refs/stash
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 05/27] Make git_path() aware of file relocation in $GIT_DIR

2014-03-01 Thread Nguyễn Thái Ngọc Duy
We allow the user to relocate certain paths out of $GIT_DIR via
environment variables, e.g. GIT_OBJECT_DIRECTORY, GIT_INDEX_FILE and
GIT_GRAFT_FILE. All callers are not supposed to use git_path() or
git_pathdup() to get those paths. Instead they must use
get_object_directory(), get_index_file() and get_graft_file()
respectively. This is inconvenient and could be missed in review
(there's git_path(objects/info/alternates) somewhere in
sha1_file.c).

This patch makes git_path() and git_pathdup() understand those
environment variables. So if you set GIT_OBJECT_DIRECTORY to /foo/bar,
git_path(objects/abc) should return /tmp/bar/abc. The same is done
for the two remaining env variables.

git rev-parse --git-path is the wrapper for script use.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/git-rev-parse.txt |  5 +
 builtin/rev-parse.c |  7 +++
 cache.h |  1 +
 environment.c   |  9 ++--
 path.c  | 46 +
 t/t0060-path-utils.sh   | 19 +
 6 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 0d2cdcd..33e4e90 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -232,6 +232,11 @@ print a message to stderr and exit with nonzero status.
repository.  If path is a gitfile then the resolved path
to the real repository is printed.
 
+--git-path path::
+   Resolve $GIT_DIR/path and takes other path relocation
+   variables such as $GIT_OBJECT_DIRECTORY,
+   $GIT_INDEX_FILE... into account.
+
 --show-cdup::
When the command is invoked from a subdirectory, show the
path of the top-level directory relative to the current
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index aaeb611..e50bc65 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -518,6 +518,13 @@ int cmd_rev_parse(int argc, const char **argv, const char 
*prefix)
for (i = 1; i  argc; i++) {
const char *arg = argv[i];
 
+   if (!strcmp(arg, --git-path)) {
+   if (!argv[i + 1])
+   die(--git-path requires an argument);
+   puts(git_path(%s, argv[i + 1]));
+   i++;
+   continue;
+   }
if (as_is) {
if (show_file(arg, output_prefix)  as_is  2)
verify_filename(prefix, arg, 0);
diff --git a/cache.h b/cache.h
index 8d3697e..6c08e4a 100644
--- a/cache.h
+++ b/cache.h
@@ -585,6 +585,7 @@ extern int fsync_object_files;
 extern int core_preload_index;
 extern int core_apply_sparse_checkout;
 extern int precomposed_unicode;
+extern int git_db_env, git_index_env, git_graft_env;
 
 /*
  * The character that begins a commented line in user-editable file
diff --git a/environment.c b/environment.c
index 4a3437d..f513479 100644
--- a/environment.c
+++ b/environment.c
@@ -82,6 +82,7 @@ static size_t namespace_len;
 
 static const char *git_dir;
 static char *git_object_dir, *git_index_file, *git_graft_file;
+int git_db_env, git_index_env, git_graft_env;
 
 /*
  * Repository-local GIT_* environment variables; see cache.h for details.
@@ -137,15 +138,19 @@ static void setup_git_env(void)
if (!git_object_dir) {
git_object_dir = xmalloc(strlen(git_dir) + 9);
sprintf(git_object_dir, %s/objects, git_dir);
-   }
+   } else
+   git_db_env = 1;
git_index_file = getenv(INDEX_ENVIRONMENT);
if (!git_index_file) {
git_index_file = xmalloc(strlen(git_dir) + 7);
sprintf(git_index_file, %s/index, git_dir);
-   }
+   } else
+   git_index_env = 1;
git_graft_file = getenv(GRAFT_ENVIRONMENT);
if (!git_graft_file)
git_graft_file = git_pathdup(info/grafts);
+   else
+   git_graft_env = 1;
if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
read_replace_refs = 0;
namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT));
diff --git a/path.c b/path.c
index ccd7228..e020530 100644
--- a/path.c
+++ b/path.c
@@ -60,13 +60,59 @@ char *mksnpath(char *buf, size_t n, const char *fmt, ...)
return cleanup_path(buf);
 }
 
+static int dir_prefix(const char *buf, const char *dir)
+{
+   int len = strlen(dir);
+   return !strncmp(buf, dir, len) 
+   (is_dir_sep(buf[len]) || buf[len] == '\0');
+}
+
+/* $buf =~ m|$dir/+$file| but without regex */
+static int is_dir_file(const char *buf, const char *dir, const char *file)
+{
+   int len = strlen(dir);
+   if (strncmp(buf, dir, len) || !is_dir_sep(buf[len]))
+   return 0;
+   while (is_dir_sep(buf[len]))
+   len++;
+   return 

[PATCH v4 19/27] wrapper.c: wrapper to open a file, fprintf then close

2014-03-01 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 cache.h   |  2 ++
 wrapper.c | 31 +++
 2 files changed, 33 insertions(+)

diff --git a/cache.h b/cache.h
index 98b5dd3..99b86d9 100644
--- a/cache.h
+++ b/cache.h
@@ -1239,6 +1239,8 @@ static inline ssize_t write_str_in_full(int fd, const 
char *str)
 {
return write_in_full(fd, str, strlen(str));
 }
+__attribute__((format (printf,3,4)))
+extern int write_file(const char *path, int fatal, const char *fmt, ...);
 
 /* pager.c */
 extern void setup_pager(void);
diff --git a/wrapper.c b/wrapper.c
index 0cc5636..5ced50d 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -455,3 +455,34 @@ struct passwd *xgetpwuid_self(void)
errno ? strerror(errno) : _(no such user));
return pw;
 }
+
+int write_file(const char *path, int fatal, const char *fmt, ...)
+{
+   struct strbuf sb = STRBUF_INIT;
+   int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0666);
+   va_list params;
+   if (fd  0) {
+   if (fatal)
+   die_errno(_(could not open %s for writing), path);
+   return -1;
+   }
+   va_start(params, fmt);
+   strbuf_vaddf(sb, fmt, params);
+   va_end(params);
+   if (write_in_full(fd, sb.buf, sb.len) != sb.len) {
+   int err = errno;
+   close(fd);
+   errno = err;
+   strbuf_release(sb);
+   if (fatal)
+   die_errno(_(could not write to %s), path);
+   return -1;
+   }
+   strbuf_release(sb);
+   if (close(fd)) {
+   if (fatal)
+   die_errno(_(could not close %s), path);
+   return -1;
+   }
+   return 0;
+}
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 16/27] setup.c: convert check_repository_format_gently to use strbuf

2014-03-01 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 setup.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/setup.c b/setup.c
index 7e5b334..5085ab1 100644
--- a/setup.c
+++ b/setup.c
@@ -288,7 +288,9 @@ void setup_work_tree(void)
 
 static int check_repository_format_gently(const char *gitdir, int *nongit_ok)
 {
-   char repo_config[PATH_MAX+1];
+   struct strbuf sb = STRBUF_INIT;
+   const char *repo_config;
+   int ret = 0;
 
/*
 * git_config() can't be used here because it calls git_pathdup()
@@ -299,7 +301,8 @@ static int check_repository_format_gently(const char 
*gitdir, int *nongit_ok)
 * Use a gentler version of git_config() to check if this repo
 * is a good one.
 */
-   snprintf(repo_config, PATH_MAX, %s/config, gitdir);
+   strbuf_addf(sb, %s/config, gitdir);
+   repo_config = sb.buf;
git_config_early(check_repository_format_version, NULL, repo_config);
if (GIT_REPO_VERSION  repository_format_version) {
if (!nongit_ok)
@@ -309,9 +312,10 @@ static int check_repository_format_gently(const char 
*gitdir, int *nongit_ok)
GIT_REPO_VERSION, repository_format_version);
warning(Please upgrade Git);
*nongit_ok = -1;
-   return -1;
+   ret = -1;
}
-   return 0;
+   strbuf_release(sb);
+   return ret;
 }
 
 /*
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 18/27] setup.c: support multi-checkout repo setup

2014-03-01 Thread Nguyễn Thái Ngọc Duy
The repo setup procedure is updated to detect $GIT_DIR/commondir and
set $GIT_COMMON_DIR properly.

The core.worktree is ignored when $GIT_DIR/commondir presents. This is
because commondir repos are intended for separate/linked checkouts
and pointing them back to a fixed core.worktree just does not make
sense.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/config.txt|  2 ++
 Documentation/git-rev-parse.txt |  3 ++
 builtin/rev-parse.c |  4 +++
 cache.h |  1 +
 environment.c   |  8 ++---
 setup.c | 33 +-
 t/t1501-worktree.sh | 76 +
 t/t1510-repo-setup.sh   |  1 +
 trace.c |  1 +
 9 files changed, 115 insertions(+), 14 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 5f4d793..313d4b3 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -381,6 +381,8 @@ false), while all other repositories are assumed to be bare 
(bare
 
 core.worktree::
Set the path to the root of the working tree.
+   If GIT_COMMON_DIR environment variable is set, core.worktree
+   is ignored and not used for determining the root of working tree.
This can be overridden by the GIT_WORK_TREE environment
variable and the '--work-tree' command line option.
The value can be an absolute path or relative to the path to
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 33e4e90..8e6ad32 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -215,6 +215,9 @@ If `$GIT_DIR` is not defined and the current directory
 is not detected to lie in a Git repository or work tree
 print a message to stderr and exit with nonzero status.
 
+--git-common-dir::
+   Show `$GIT_COMMON_DIR` if defined, else `$GIT_DIR`.
+
 --is-inside-git-dir::
When the current working directory is below the repository
directory print true, otherwise false.
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index e50bc65..c7057ce 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -744,6 +744,10 @@ int cmd_rev_parse(int argc, const char **argv, const char 
*prefix)
printf(%s%s.git\n, cwd, len  cwd[len-1] != 
'/' ? / : );
continue;
}
+   if (!strcmp(arg, --git-common-dir)) {
+   puts(get_git_common_dir());
+   continue;
+   }
if (!strcmp(arg, --resolve-git-dir)) {
const char *gitdir = resolve_gitdir(argv[i+1]);
if (!gitdir)
diff --git a/cache.h b/cache.h
index 51ade32..98b5dd3 100644
--- a/cache.h
+++ b/cache.h
@@ -407,6 +407,7 @@ extern char *get_object_directory(void);
 extern char *get_index_file(void);
 extern char *get_graft_file(void);
 extern int set_git_dir(const char *path);
+extern int get_common_dir(struct strbuf *sb, const char *gitdir);
 extern const char *get_git_namespace(void);
 extern const char *strip_namespace(const char *namespaced_ref);
 extern const char *get_git_work_tree(void);
diff --git a/environment.c b/environment.c
index c998120..0999fc1 100644
--- a/environment.c
+++ b/environment.c
@@ -126,6 +126,7 @@ static char *expand_namespace(const char *raw_namespace)
 
 static void setup_git_env(void)
 {
+   struct strbuf sb = STRBUF_INIT;
const char *gitfile;
const char *shallow_file;
 
@@ -134,12 +135,9 @@ static void setup_git_env(void)
git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
gitfile = read_gitfile(git_dir);
git_dir = xstrdup(gitfile ? gitfile : git_dir);
-   git_common_dir = getenv(GIT_COMMON_DIR_ENVIRONMENT);
-   if (git_common_dir) {
+   if (get_common_dir(sb, git_dir))
git_common_dir_env = 1;
-   git_common_dir = xstrdup(git_common_dir);
-   } else
-   git_common_dir = git_dir;
+   git_common_dir = strbuf_detach(sb, NULL);
git_object_dir = getenv(DB_ENVIRONMENT);
if (!git_object_dir) {
git_object_dir = xmalloc(strlen(git_common_dir) + 9);
diff --git a/setup.c b/setup.c
index 42849f3..40ce191 100644
--- a/setup.c
+++ b/setup.c
@@ -170,14 +170,15 @@ void verify_non_filename(const char *prefix, const char 
*arg)
'git command [revision...] -- [file...]', arg);
 }
 
-static void get_common_dir(struct strbuf *sb, const char *gitdir)
+int get_common_dir(struct strbuf *sb, const char *gitdir)
 {
struct strbuf data = STRBUF_INIT;
struct strbuf path = STRBUF_INIT;
const char *git_common_dir = getenv(GIT_COMMON_DIR_ENVIRONMENT);
+   int ret = 0;
if (git_common_dir) {
strbuf_addstr(sb, git_common_dir);

[PATCH v4 15/27] setup.c: detect $GIT_COMMON_DIR in is_git_directory()

2014-03-01 Thread Nguyễn Thái Ngọc Duy
If the file $GIT_DIR/commondir exists, it contains the value of
$GIT_COMMON_DIR.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/gitrepository-layout.txt |  7 ++
 setup.c| 43 +-
 2 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/Documentation/gitrepository-layout.txt 
b/Documentation/gitrepository-layout.txt
index 10672a1..f72ce75 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -233,6 +233,13 @@ shallow::
file is ignored $GIT_COMMON_DIR is set and
$GIT_COMMON_DIR/shallow will be used instead.
 
+commondir::
+   If this file exists, $GIT_COMMON_DIR (see linkgit:git[1]) will
+   be set to the path specified in this file if it is not
+   explicitly set. If the specified path is relative, it is
+   relative to $GIT_DIR. The repository with commondir is
+   incomplete without the repository pointed by commondir.
+
 modules::
Contains the git-repositories of the submodules. This
directory is ignored $GIT_COMMON_DIR is set and
diff --git a/setup.c b/setup.c
index 4994437..7e5b334 100644
--- a/setup.c
+++ b/setup.c
@@ -170,6 +170,33 @@ void verify_non_filename(const char *prefix, const char 
*arg)
'git command [revision...] -- [file...]', arg);
 }
 
+static void get_common_dir(struct strbuf *sb, const char *gitdir)
+{
+   struct strbuf data = STRBUF_INIT;
+   struct strbuf path = STRBUF_INIT;
+   const char *git_common_dir = getenv(GIT_COMMON_DIR_ENVIRONMENT);
+   if (git_common_dir) {
+   strbuf_addstr(sb, git_common_dir);
+   return;
+   }
+   strbuf_addf(path, %s/commondir, gitdir);
+   if (file_exists(path.buf)) {
+   if (strbuf_read_file(data, path.buf, 0) = 0)
+   die_errno(_(failed to read %s), path.buf);
+   while (data.len  (data.buf[data.len - 1] == '\n' ||
+   data.buf[data.len - 1] == '\r'))
+   data.len--;
+   data.buf[data.len] = '\0';
+   strbuf_reset(path);
+   if (!is_absolute_path(data.buf))
+   strbuf_addf(path, %s/, gitdir);
+   strbuf_addbuf(path, data);
+   strbuf_addstr(sb, real_path(path.buf));
+   } else
+   strbuf_addstr(sb, gitdir);
+   strbuf_release(data);
+   strbuf_release(path);
+}
 
 /*
  * Test if it looks like we're at a git directory.
@@ -188,13 +215,22 @@ int is_git_directory(const char *suspect)
int ret = 0;
size_t len;
 
-   strbuf_addstr(path, suspect);
+   /* Check worktree-related signatures */
+   strbuf_addf(path, %s/HEAD, suspect);
+   if (validate_headref(path.buf))
+   goto done;
+
+   strbuf_reset(path);
+   get_common_dir(path, suspect);
len = path.len;
+
+   /* Check non-worktree-related signatures */
if (getenv(DB_ENVIRONMENT)) {
if (access(getenv(DB_ENVIRONMENT), X_OK))
goto done;
}
else {
+   strbuf_setlen(path, len);
strbuf_addstr(path, /objects);
if (access(path.buf, X_OK))
goto done;
@@ -205,11 +241,6 @@ int is_git_directory(const char *suspect)
if (access(path.buf, X_OK))
goto done;
 
-   strbuf_setlen(path, len);
-   strbuf_addstr(path, /HEAD);
-   if (validate_headref(path.buf))
-   goto done;
-
ret = 1;
 done:
strbuf_release(path);
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 14/27] setup.c: convert is_git_directory() to use strbuf

2014-03-01 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 setup.c | 37 +
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/setup.c b/setup.c
index 6c3f85f..4994437 100644
--- a/setup.c
+++ b/setup.c
@@ -184,31 +184,36 @@ void verify_non_filename(const char *prefix, const char 
*arg)
  */
 int is_git_directory(const char *suspect)
 {
-   char path[PATH_MAX];
-   size_t len = strlen(suspect);
+   struct strbuf path = STRBUF_INIT;
+   int ret = 0;
+   size_t len;
 
-   if (PATH_MAX = len + strlen(/objects))
-   die(Too long path: %.*s, 60, suspect);
-   strcpy(path, suspect);
+   strbuf_addstr(path, suspect);
+   len = path.len;
if (getenv(DB_ENVIRONMENT)) {
if (access(getenv(DB_ENVIRONMENT), X_OK))
-   return 0;
+   goto done;
}
else {
-   strcpy(path + len, /objects);
-   if (access(path, X_OK))
-   return 0;
+   strbuf_addstr(path, /objects);
+   if (access(path.buf, X_OK))
+   goto done;
}
 
-   strcpy(path + len, /refs);
-   if (access(path, X_OK))
-   return 0;
+   strbuf_setlen(path, len);
+   strbuf_addstr(path, /refs);
+   if (access(path.buf, X_OK))
+   goto done;
 
-   strcpy(path + len, /HEAD);
-   if (validate_headref(path))
-   return 0;
+   strbuf_setlen(path, len);
+   strbuf_addstr(path, /HEAD);
+   if (validate_headref(path.buf))
+   goto done;
 
-   return 1;
+   ret = 1;
+done:
+   strbuf_release(path);
+   return ret;
 }
 
 int is_inside_git_dir(void)
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 17/27] setup.c: detect $GIT_COMMON_DIR check_repository_format_gently()

2014-03-01 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 setup.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/setup.c b/setup.c
index 5085ab1..42849f3 100644
--- a/setup.c
+++ b/setup.c
@@ -292,6 +292,10 @@ static int check_repository_format_gently(const char 
*gitdir, int *nongit_ok)
const char *repo_config;
int ret = 0;
 
+   get_common_dir(sb, gitdir);
+   strbuf_addstr(sb, /config);
+   repo_config = sb.buf;
+
/*
 * git_config() can't be used here because it calls git_pathdup()
 * to get $GIT_CONFIG/config. That call will make setup_git_env()
@@ -301,8 +305,6 @@ static int check_repository_format_gently(const char 
*gitdir, int *nongit_ok)
 * Use a gentler version of git_config() to check if this repo
 * is a good one.
 */
-   strbuf_addf(sb, %s/config, gitdir);
-   repo_config = sb.buf;
git_config_early(check_repository_format_version, NULL, repo_config);
if (GIT_REPO_VERSION  repository_format_version) {
if (!nongit_ok)
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 22/27] checkout: clean up half-prepared directories in --to mode

2014-03-01 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/checkout.c | 49 +++--
 1 file changed, 47 insertions(+), 2 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index fa7b54a..28f9ac1 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -20,6 +20,7 @@
 #include resolve-undo.h
 #include submodule.h
 #include argv-array.h
+#include sigchain.h
 
 static const char * const checkout_usage[] = {
N_(git checkout [options] branch),
@@ -814,6 +815,35 @@ static int switch_branches(const struct checkout_opts 
*opts,
return ret || writeout_error;
 }
 
+static const char *junk_work_tree;
+static const char *junk_git_dir;
+static int is_junk;
+static pid_t junk_pid;
+
+static void remove_junk(void)
+{
+   struct strbuf sb = STRBUF_INIT;
+   if (!is_junk || getpid() != junk_pid)
+   return;
+   if (junk_git_dir) {
+   strbuf_addstr(sb, junk_git_dir);
+   remove_dir_recursively(sb, 0);
+   strbuf_reset(sb);
+   }
+   if (junk_work_tree) {
+   strbuf_addstr(sb, junk_work_tree);
+   remove_dir_recursively(sb, 0);
+   strbuf_reset(sb);
+   }
+}
+
+static void remove_junk_on_signal(int signo)
+{
+   remove_junk();
+   sigchain_pop(signo);
+   raise(signo);
+}
+
 static int prepare_linked_checkout(const struct checkout_opts *opts,
   struct branch_info *new)
 {
@@ -822,7 +852,7 @@ static int prepare_linked_checkout(const struct 
checkout_opts *opts,
const char *path = opts-new_worktree, *name;
struct stat st;
struct child_process cp;
-   int counter = 0, len;
+   int counter = 0, len, ret;
 
if (!new-commit)
die(_(no branch specified));
@@ -848,13 +878,21 @@ static int prepare_linked_checkout(const struct 
checkout_opts *opts,
strbuf_addf(sb_repo, %d, counter);
}
name = strrchr(sb_repo.buf, '/') + 1;
+
+   junk_pid = getpid();
+   atexit(remove_junk);
+   sigchain_push_common(remove_junk_on_signal);
+
if (mkdir(sb_repo.buf, 0777))
die_errno(_(could not create directory of '%s'), sb_repo.buf);
+   junk_git_dir = sb_repo.buf;
+   is_junk = 1;
 
strbuf_addf(sb_git, %s/.git, path);
if (safe_create_leading_directories_const(sb_git.buf))
die_errno(_(could not create leading directories of '%s'),
  sb_git.buf);
+   junk_work_tree = path;
 
write_file(sb_git.buf, 1, gitdir: %s/repos/%s\n,
   real_path(get_git_common_dir()), name);
@@ -879,7 +917,14 @@ static int prepare_linked_checkout(const struct 
checkout_opts *opts,
memset(cp, 0, sizeof(cp));
cp.git_cmd = 1;
cp.argv = opts-saved_argv;
-   return run_command(cp);
+   ret = run_command(cp);
+   if (!ret)
+   is_junk = 0;
+   strbuf_release(sb);
+   strbuf_release(sb_repo);
+   strbuf_release(sb_git);
+   return ret;
+
 }
 
 static int git_checkout_config(const char *var, const char *value, void *cb)
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 23/27] checkout: detach if the branch is already checked out elsewhere

2014-03-01 Thread Nguyễn Thái Ngọc Duy
The normal rule is anything outside refs/heads/ is detached. This
increases strictness of the rule a bit more: if the branch is checked
out (either in $GIT_COMMON_DIR/HEAD or any $GIT_DIR/repos/.../HEAD)
then it's detached as well.

A hint is given so the user knows where to go and do something there
if they still want to checkout undetached here.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/checkout.c | 80 ++
 t/t2025-checkout-to.sh | 15 --
 2 files changed, 92 insertions(+), 3 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 28f9ac1..1675808 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -433,6 +433,11 @@ struct branch_info {
const char *name; /* The short name used */
const char *path; /* The full name of a real branch */
struct commit *commit; /* The named commit */
+   /*
+* if not null the branch is detached because it's already
+* checked out in this checkout
+*/
+   char *checkout;
 };
 
 static void setup_branch_path(struct branch_info *branch)
@@ -640,6 +645,11 @@ static void update_refs_for_switch(const struct 
checkout_opts *opts,
if (old-path  advice_detached_head)
detach_advice(new-name);
describe_detached_head(_(HEAD is now at), 
new-commit);
+   if (new-checkout  !*new-checkout)
+   fprintf(stderr, _(hint: the main checkout is 
holding this branch\n));
+   else if (new-checkout)
+   fprintf(stderr, _(hint: the linked checkout %s 
is holding this branch\n),
+   new-checkout);
}
} else if (new-path) { /* Switch branches. */
create_symref(HEAD, new-path, msg.buf);
@@ -982,6 +992,73 @@ static const char *unique_tracking_name(const char *name, 
unsigned char *sha1)
return NULL;
 }
 
+static int check_linked_checkout(struct branch_info *new,
+ const char *name, const char *path)
+{
+   struct strbuf sb = STRBUF_INIT;
+   char *start, *end;
+   if (strbuf_read_file(sb, path, 0)  0)
+   return 0;
+   if (!starts_with(sb.buf, ref:)) {
+   strbuf_release(sb);
+   return 0;
+   }
+
+   start = sb.buf + 4;
+   while (isspace(*start))
+   start++;
+   end = start;
+   while (*end  !isspace(*end))
+   end++;
+   if (!strncmp(start, new-path, end - start) 
+   new-path[end - start] == '\0') {
+   strbuf_release(sb);
+   new-path = NULL; /* detach */
+   new-checkout = xstrdup(name); /* reason */
+   return 1;
+   }
+   strbuf_release(sb);
+   return 0;
+}
+
+static void check_linked_checkouts(struct branch_info *new)
+{
+   struct strbuf path = STRBUF_INIT;
+   DIR *dir;
+   struct dirent *d;
+
+   strbuf_addf(path, %s/repos, get_git_common_dir());
+   if ((dir = opendir(path.buf)) == NULL) {
+   strbuf_release(path);
+   return;
+   }
+
+   strbuf_reset(path);
+   strbuf_addf(path, %s/HEAD, get_git_common_dir());
+   /*
+* $GIT_COMMON_DIR/HEAD is practically outside
+* $GIT_DIR so resolve_ref_unsafe() won't work (it
+* uses git_path). Parse the ref ourselves.
+*/
+   if (check_linked_checkout(new, , path.buf)) {
+   strbuf_release(path);
+   closedir(dir);
+   return;
+   }
+
+   while ((d = readdir(dir)) != NULL) {
+   if (!strcmp(d-d_name, .) || !strcmp(d-d_name, ..))
+   continue;
+   strbuf_reset(path);
+   strbuf_addf(path, %s/repos/%s/HEAD,
+   get_git_common_dir(), d-d_name);
+   if (check_linked_checkout(new, d-d_name, path.buf))
+   break;
+   }
+   strbuf_release(path);
+   closedir(dir);
+}
+
 static int parse_branchname_arg(int argc, const char **argv,
int dwim_new_local_branch_ok,
struct branch_info *new,
@@ -1109,6 +1186,9 @@ static int parse_branchname_arg(int argc, const char 
**argv,
else
new-path = NULL; /* not an existing branch */
 
+   if (new-path)
+   check_linked_checkouts(new);
+
new-commit = lookup_commit_reference_gently(rev, 1);
if (!new-commit) {
/* not a commit */
diff --git a/t/t2025-checkout-to.sh b/t/t2025-checkout-to.sh
index 5ec49e2..2d35a9b 100755
--- a/t/t2025-checkout-to.sh
+++ b/t/t2025-checkout-to.sh
@@ -13,13 +13,14 @@ test_expect_success 'checkout --to not updating paths' '
 '
 
 test_expect_success 'checkout --to a new worktree' '
+   git 

[PATCH v4 21/27] checkout: support checking out into a new working directory

2014-03-01 Thread Nguyễn Thái Ngọc Duy
git checkout --to sets up a new working directory with a .git file
pointing to $GIT_DIR/repos/id. It then executes git checkout again
on the new worktree with the same arguments except --to is taken
out. The second checkout execution, which is not contaminated with any
info from the current repository, will actually check out and
everything that normal git checkout does.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/git-checkout.txt | 34 +
 Documentation/git.txt  |  3 +-
 Documentation/gitrepository-layout.txt |  7 +++
 builtin/checkout.c | 93 +-
 path.c |  2 +-
 t/t2025-checkout-to.sh (new +x)| 48 ++
 6 files changed, 183 insertions(+), 4 deletions(-)
 create mode 100755 t/t2025-checkout-to.sh

diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 33ad2ad..fcf73b2 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -225,6 +225,13 @@ This means that you can use `git checkout -p` to 
selectively discard
 edits from your current working tree. See the ``Interactive Mode''
 section of linkgit:git-add[1] to learn how to operate the `--patch` mode.
 
+--to=path::
+   Check out a new branch in a separate working directory at
+   `path`. A new working directory is linked to the current
+   repository, sharing everything except working directory
+   specific files such as HEAD, index... See MULTIPLE CHECKOUT
+   MODE section for more information.
+
 branch::
Branch to checkout; if it refers to a branch (i.e., a name that,
when prepended with refs/heads/, is a valid ref), then that
@@ -388,6 +395,33 @@ $ git reflog -2 HEAD # or
 $ git log -g -2 HEAD
 
 
+MULTIPLE CHECKOUT MODE
+---
+Normally a working directory is attached to repository. When git
+checkout --to is used, a new working directory is attached to the
+current repository. This new working directory is called linked
+checkout as compared to the main checkout prepared by git init or
+git clone. A repository has one main checkout and zero or more
+linked checkouts.
+
+All checkouts share the same repository. Linked checkouts see the
+repository a bit different from the main checkout. When the checkout
+new reads the path $GIT_DIR/HEAD for example, the actual path
+returned could be $GIT_DIR/repos/new/HEAD. This ensures checkouts
+won't step on each other.
+
+Each linked checkout has a private space in $GIT_DIR/repos, usually
+named after the base name of the working directory with a number added
+to make it unique. The linked checkout's $GIT_DIR points to this
+private space while $GIT_COMMON_DIR points to the main checkout's
+$GIT_DIR. These settings are done by git checkout --to.
+
+Because in this mode $GIT_DIR becomes a lightweight virtual file
+system where a path could be rewritten to some place else, accessing
+$GIT_DIR from scripts should use `git rev-parse --git-path` to resolve
+a path instead of using it directly unless the path is known to be
+private to the working directory.
+
 EXAMPLES
 
 
diff --git a/Documentation/git.txt b/Documentation/git.txt
index b094b1f..bdb9b0f 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -777,7 +777,8 @@ Git so take care if using Cogito etc.
If this variable is set to a path, non-worktree files that are
normally in $GIT_DIR will be taken from this path
instead. Worktree-specific files such as HEAD or index are
-   taken from $GIT_DIR. See linkgit:gitrepository-layout[5] for
+   taken from $GIT_DIR. See linkgit:gitrepository-layout[5] and
+   the section 'MULTIPLE CHECKOUT MODE' in linkgit:checkout[1]
details. This variable has lower precedence than other path
variables such as GIT_INDEX_FILE, GIT_OBJECT_DIRECTORY...
 
diff --git a/Documentation/gitrepository-layout.txt 
b/Documentation/gitrepository-layout.txt
index f72ce75..418e5c8 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -245,6 +245,13 @@ modules::
directory is ignored $GIT_COMMON_DIR is set and
$GIT_COMMON_DIR/modules will be used instead.
 
+repos::
+   Contains worktree specific information of linked
+   checkouts. Each subdirectory contains the worktree-related
+   part of a linked checkout. This directory is ignored
+   $GIT_COMMON_DIR is set and $GIT_COMMON_DIR/repos will be
+   used instead.
+
 SEE ALSO
 
 linkgit:git-init[1],
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 0570e41..fa7b54a 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -48,6 +48,10 @@ struct checkout_opts {
const char *prefix;
struct pathspec pathspec;
struct tree *source_tree;
+
+   const char *new_worktree;
+   const char **saved_argv;
+   int 

[PATCH v4 25/27] gc: style change -- no SP before closing bracket

2014-03-01 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/gc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/builtin/gc.c b/builtin/gc.c
index c19545d..39d9b27 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -260,7 +260,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
OPT__QUIET(quiet, N_(suppress progress reporting)),
{ OPTION_STRING, 0, prune, prune_expire, N_(date),
N_(prune unreferenced objects),
-   PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire },
+   PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire},
OPT_BOOL(0, aggressive, aggressive, N_(be more thorough 
(increased runtime))),
OPT_BOOL(0, auto, auto_gc, N_(enable auto-gc mode)),
OPT_BOOL(0, force, force, N_(force running gc even if there 
may be another gc running)),
@@ -273,7 +273,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
argv_array_pushl(pack_refs_cmd, pack-refs, --all, --prune, NULL);
argv_array_pushl(reflog, reflog, expire, --all, NULL);
argv_array_pushl(repack, repack, -d, -l, NULL);
-   argv_array_pushl(prune, prune, --expire, NULL );
+   argv_array_pushl(prune, prune, --expire, NULL);
argv_array_pushl(rerere, rerere, gc, NULL);
 
git_config(gc_config, NULL);
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 24/27] prune: strategies for linked checkouts

2014-03-01 Thread Nguyễn Thái Ngọc Duy
(alias R=$GIT_COMMON_DIR/repos/id)

 - linked checkouts are supposed to keep its location in $R/gitdir up
   to date. The use case is auto fixup after a manual checkout move.

 - linked checkouts are supposed to update mtime of $R/gitdir. If
   $R/gitdir's mtime is older than a limit, and it points to nowhere,
   repos/id is to be pruned.

 - git checkout --to is supposed to create $R/locked if the new repo
   is on a different partition than the shared one. The main use case
   is when the checkout is on a portable device and may not be
   available at prune time.

   If $R/locked exists, repos/id is not supposed to be pruned. If
   $R/locked exists and $R/gitdir's mtime is older than a really long
   limit, warn about old unused repo.

 - git checkout --to is supposed to make a hard link named $R/link
   pointing to the .git file on supported file systems to help detect
   the user manually deleting the checkout. If $R/link exists and its
   link count is greated than 1, the repo is kept.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/git-prune.txt|  3 ++
 Documentation/gitrepository-layout.txt | 19 +
 builtin/checkout.c | 36 -
 builtin/prune.c| 74 ++
 compat/mingw.h |  1 +
 git-compat-util.h  |  4 ++
 setup.c| 13 ++
 7 files changed, 149 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-prune.txt b/Documentation/git-prune.txt
index 058ac0d..7babf11 100644
--- a/Documentation/git-prune.txt
+++ b/Documentation/git-prune.txt
@@ -48,6 +48,9 @@ OPTIONS
 --expire time::
Only expire loose objects older than time.
 
+--repos::
+   Prune directories in $GIT_DIR/repos.
+
 head...::
In addition to objects
reachable from any of our references, keep objects
diff --git a/Documentation/gitrepository-layout.txt 
b/Documentation/gitrepository-layout.txt
index 418e5c8..2dc6901 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -252,6 +252,25 @@ repos::
$GIT_COMMON_DIR is set and $GIT_COMMON_DIR/repos will be
used instead.
 
+repos/id/gitdir::
+   A text file containing the absolute path back to the .git file
+   that points to here. This is used to check if the linked
+   repository has been manually removed and there is no need to
+   keep this directory any more. mtime of this file should be
+   updated every time the linked repository is accessed.
+
+repos/id/locked::
+   If this file exists, the linked repository may be on a
+   portable device and not available. It does not mean that the
+   linked repository is gone and `repos/id` could be
+   removed. The file's content contains a reason string on why
+   the repository is locked.
+
+repos/id/link::
+   If this file exists, it is a hard link to the linked .git
+   file. It is used to detect if the linked repository is
+   manually removed.
+
 SEE ALSO
 
 linkgit:git-init[1],
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 1675808..1fc85d3 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -854,6 +854,17 @@ static void remove_junk_on_signal(int signo)
raise(signo);
 }
 
+static dev_t get_device_or_die(const char *path)
+{
+   struct stat buf;
+   if (stat(path, buf))
+   die_errno(failed to stat '%s', path);
+   /* Ah Windows! Make different drives different partitions */
+   if (is_windows())
+   buf.st_dev = toupper(real_path(path)[0]);
+   return buf.st_dev;
+}
+
 static int prepare_linked_checkout(const struct checkout_opts *opts,
   struct branch_info *new)
 {
@@ -862,7 +873,7 @@ static int prepare_linked_checkout(const struct 
checkout_opts *opts,
const char *path = opts-new_worktree, *name;
struct stat st;
struct child_process cp;
-   int counter = 0, len, ret;
+   int counter = 0, len, keep_locked = 0, ret;
 
if (!new-commit)
die(_(no branch specified));
@@ -898,12 +909,18 @@ static int prepare_linked_checkout(const struct 
checkout_opts *opts,
junk_git_dir = sb_repo.buf;
is_junk = 1;
 
+   strbuf_addf(sb, %s/locked, sb_repo.buf);
+   write_file(sb.buf, 1, initializing\n);
+
strbuf_addf(sb_git, %s/.git, path);
if (safe_create_leading_directories_const(sb_git.buf))
die_errno(_(could not create leading directories of '%s'),
  sb_git.buf);
junk_work_tree = path;
 
+   strbuf_reset(sb);
+   strbuf_addf(sb, %s/gitdir, sb_repo.buf);
+   write_file(sb.buf, 1, %s\n, real_path(sb_git.buf));
write_file(sb_git.buf, 1, gitdir: %s/repos/%s\n,
   real_path(get_git_common_dir()), name);
/*
@@ -912,12 +929,24 

[PATCH v4 20/27] use new wrapper write_file() for simple file writing

2014-03-01 Thread Nguyễn Thái Ngọc Duy
This fixes common problems in these code about error handling,
forgetting to close the file handle after fprintf() fails, or not
printing out the error string..

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/branch.c  |  4 +---
 builtin/init-db.c |  7 +--
 daemon.c  | 11 +--
 submodule.c   |  9 ++---
 transport.c   |  8 +++-
 5 files changed, 8 insertions(+), 31 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index b4d7716..3eebdbc 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -754,7 +754,6 @@ static const char edit_description[] = BRANCH_DESCRIPTION;
 
 static int edit_branch_description(const char *branch_name)
 {
-   FILE *fp;
int status;
struct strbuf buf = STRBUF_INIT;
struct strbuf name = STRBUF_INIT;
@@ -767,8 +766,7 @@ static int edit_branch_description(const char *branch_name)
  %s\n
Lines starting with '%c' will be stripped.\n,
branch_name, comment_line_char);
-   fp = fopen(git_path(edit_description), w);
-   if ((fwrite(buf.buf, 1, buf.len, fp)  buf.len) || fclose(fp)) {
+   if (write_file(git_path(edit_description), 0, %s, buf.buf)) {
strbuf_release(buf);
return error(_(could not write branch description template: 
%s),
 strerror(errno));
diff --git a/builtin/init-db.c b/builtin/init-db.c
index c7c76bb..081e512 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -342,7 +342,6 @@ int set_git_dir_init(const char *git_dir, const char 
*real_git_dir,
 static void separate_git_dir(const char *git_dir)
 {
struct stat st;
-   FILE *fp;
 
if (!stat(git_link, st)) {
const char *src;
@@ -358,11 +357,7 @@ static void separate_git_dir(const char *git_dir)
die_errno(_(unable to move %s to %s), src, git_dir);
}
 
-   fp = fopen(git_link, w);
-   if (!fp)
-   die(_(Could not create git link %s), git_link);
-   fprintf(fp, gitdir: %s\n, git_dir);
-   fclose(fp);
+   write_file(git_link, 1, gitdir: %s\n, git_dir);
 }
 
 int init_db(const char *template_dir, unsigned int flags)
diff --git a/daemon.c b/daemon.c
index 503e039..b880d30 100644
--- a/daemon.c
+++ b/daemon.c
@@ -1122,15 +1122,6 @@ static void daemonize(void)
 }
 #endif
 
-static void store_pid(const char *path)
-{
-   FILE *f = fopen(path, w);
-   if (!f)
-   die_errno(cannot open pid file '%s', path);
-   if (fprintf(f, %PRIuMAX\n, (uintmax_t) getpid())  0 || fclose(f) 
!= 0)
-   die_errno(failed to write pid file '%s', path);
-}
-
 static int serve(struct string_list *listen_addr, int listen_port,
 struct credentials *cred)
 {
@@ -1339,7 +1330,7 @@ int main(int argc, char **argv)
sanitize_stdfds();
 
if (pid_file)
-   store_pid(pid_file);
+   write_file(pid_file, 1, %PRIuMAX\n, (uintmax_t) getpid());
 
/* prepare argv for serving-processes */
cld_argv = xmalloc(sizeof (char *) * (argc + 2));
diff --git a/submodule.c b/submodule.c
index 613857e..fe5748d 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1135,16 +1135,11 @@ void connect_work_tree_and_git_dir(const char 
*work_tree, const char *git_dir)
struct strbuf file_name = STRBUF_INIT;
struct strbuf rel_path = STRBUF_INIT;
const char *real_work_tree = xstrdup(real_path(work_tree));
-   FILE *fp;
 
/* Update gitfile */
strbuf_addf(file_name, %s/.git, work_tree);
-   fp = fopen(file_name.buf, w);
-   if (!fp)
-   die(_(Could not create git link %s), file_name.buf);
-   fprintf(fp, gitdir: %s\n, relative_path(git_dir, real_work_tree,
- rel_path));
-   fclose(fp);
+   write_file(file_name.buf, 1, gitdir: %s\n,
+  relative_path(git_dir, real_work_tree, rel_path));
 
/* Update core.worktree setting */
strbuf_reset(file_name);
diff --git a/transport.c b/transport.c
index ca7bb44..2df8a15 100644
--- a/transport.c
+++ b/transport.c
@@ -294,7 +294,6 @@ static int write_one_ref(const char *name, const unsigned 
char *sha1,
 {
struct strbuf *buf = data;
int len = buf-len;
-   FILE *f;
 
/* when called via for_each_ref(), flags is non-zero */
if (flags  !starts_with(name, refs/heads/) 
@@ -303,10 +302,9 @@ static int write_one_ref(const char *name, const unsigned 
char *sha1,
 
strbuf_addstr(buf, name);
if (safe_create_leading_directories(buf-buf) ||
-   !(f = fopen(buf-buf, w)) ||
-   fprintf(f, %s\n, sha1_to_hex(sha1))  0 ||
-   fclose(f))
-   return error(problems writing temporary file %s, buf-buf);
+   write_file(buf-buf, 0, %s\n, sha1_to_hex(sha1)))
+   return 

[PATCH v4 27/27] count-objects: report unused files in $GIT_DIR/repos/...

2014-03-01 Thread Nguyễn Thái Ngọc Duy
In linked checkouts, borrowed parts like config is taken from
$GIT_COMMON_DIR. $GIT_DIR/config is never used. Report them as
garbage.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/count-objects.c | 37 -
 path.c  |  4 
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/builtin/count-objects.c b/builtin/count-objects.c
index a7f70cb..725cd5f 100644
--- a/builtin/count-objects.c
+++ b/builtin/count-objects.c
@@ -78,6 +78,39 @@ static void count_objects(DIR *d, char *path, int len, int 
verbose,
}
 }
 
+static void report_linked_checkout_garbage(void)
+{
+   /*
+* must be more or less in sync with * path.c:update_common_dir().
+*
+* logs is let slip because logs/HEAD is in $GIT_DIR but the
+* remaining in $GIT_COMMON_DIR. Probably not worth traversing
+* the entire logs directory for that.
+*
+* The same gc.pid for because it's a temporary file.
+*/
+   const char *list[] = {
+   branches, hooks, info, lost-found, modules,
+   objects, refs, remotes, rr-cache, svn,
+   config, packed-refs, shallow, NULL
+   };
+   struct strbuf sb = STRBUF_INIT;
+   const char **p;
+   int len;
+
+   if (!file_exists(git_path(commondir)))
+   return;
+   strbuf_addf(sb, %s/, get_git_dir());
+   len = sb.len;
+   for (p = list; *p; p++) {
+   strbuf_setlen(sb, len);
+   strbuf_addstr(sb, *p);
+   if (file_exists(sb.buf))
+   report_garbage(unused in linked checkout, sb.buf);
+   }
+   strbuf_release(sb);
+}
+
 static char const * const count_objects_usage[] = {
N_(git count-objects [-v] [-H | --human-readable]),
NULL
@@ -102,8 +135,10 @@ int cmd_count_objects(int argc, const char **argv, const 
char *prefix)
/* we do not take arguments other than flags for now */
if (argc)
usage_with_options(count_objects_usage, opts);
-   if (verbose)
+   if (verbose) {
report_garbage = real_report_garbage;
+   report_linked_checkout_garbage();
+   }
memcpy(path, objdir, len);
if (len  objdir[len-1] != '/')
path[len++] = '/';
diff --git a/path.c b/path.c
index 47383ff..2e6035d 100644
--- a/path.c
+++ b/path.c
@@ -92,6 +92,10 @@ static void replace_dir(struct strbuf *buf, int len, const 
char *newdir)
 
 static void update_common_dir(struct strbuf *buf, int git_dir_len)
 {
+   /*
+* Remember to report_linked_checkout_garbage()
+* builtin/count-objects.c
+*/
const char *common_dir_list[] = {
branches, hooks, info, logs, lost-found, modules,
objects, refs, remotes, repos, rr-cache, svn,
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] branch: die when setting branch as own upstream

2014-03-01 Thread Brian Gesiak
Branch set as own upstream using one of the following commands returns
immediately with an exit code of 0:

- `git branch --set-upstream-to foo refs/heads/foo`
- `git branch --force --track foo foo`

Since neither of these actions currently set the upstream, an exit code
of 0 is misleading. Instead, exit with a status code indicating failure
by using the die function.

Signed-off-by: Brian Gesiak modoca...@gmail.com
---
 branch.c  | 9 ++---
 t/t3200-branch.sh | 6 +++---
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/branch.c b/branch.c
index e163f3c..9bac8b5 100644
--- a/branch.c
+++ b/branch.c
@@ -54,13 +54,8 @@ void install_branch_config(int flag, const char *local, 
const char *origin, cons
struct strbuf key = STRBUF_INIT;
int rebasing = should_setup_rebase(origin);
 
-   if (shortname
-!strcmp(local, shortname)
-!origin) {
-   warning(_(Not setting branch %s as its own upstream.),
-   local);
-   return;
-   }
+   if (shortname  !strcmp(local, shortname)  !origin)
+   die(_(Not setting branch %s as its own upstream.), local);
 
strbuf_addf(key, branch.%s.remote, local);
git_config_set(key.buf, origin ? origin : .);
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 6164126..3ac493f 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -507,10 +507,10 @@ EOF
test_cmp expected actual
 '
 
-test_expect_success '--set-upstream-to shows warning if used to set branch as 
own upstream' '
-   git branch --set-upstream-to refs/heads/my13 my13 2actual 
+test_expect_success '--set-upstream-to fails if used to set branch as own 
upstream' '
+   test_must_fail git branch --set-upstream-to refs/heads/my13 my13 
2actual 
cat expected EOF 
-warning: Not setting branch my13 as its own upstream.
+fatal: Not setting branch my13 as its own upstream.
 EOF
test_i18ncmp expected actual
 '
-- 
1.8.3.4 (Apple Git-47)

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 26/27] gc: support prune --repos

2014-03-01 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/config.txt |  6 ++
 builtin/gc.c | 17 +
 2 files changed, 23 insertions(+)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 313d4b3..438b213 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1183,6 +1183,12 @@ gc.pruneexpire::
now may be used to disable this  grace period and always prune
unreachable objects immediately.
 
+gc.prunereposexpire::
+   When 'git gc' is run, it will call 'prune --repos --expire 
3.months.ago'.
+   Override the grace period with this config variable.  The value
+   now may be used to disable this  grace period and always prune
+   $GIT_DIR/repos immediately.
+
 gc.reflogexpire::
 gc.pattern.reflogexpire::
'git reflog expire' removes reflog entries older than
diff --git a/builtin/gc.c b/builtin/gc.c
index 39d9b27..85c3c0c 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -30,11 +30,13 @@ static int aggressive_window = 250;
 static int gc_auto_threshold = 6700;
 static int gc_auto_pack_limit = 50;
 static const char *prune_expire = 2.weeks.ago;
+static const char *prune_repos_expire = 3.months.ago;
 
 static struct argv_array pack_refs_cmd = ARGV_ARRAY_INIT;
 static struct argv_array reflog = ARGV_ARRAY_INIT;
 static struct argv_array repack = ARGV_ARRAY_INIT;
 static struct argv_array prune = ARGV_ARRAY_INIT;
+static struct argv_array prune_repos = ARGV_ARRAY_INIT;
 static struct argv_array rerere = ARGV_ARRAY_INIT;
 
 static char *pidfile;
@@ -81,6 +83,14 @@ static int gc_config(const char *var, const char *value, 
void *cb)
}
return git_config_string(prune_expire, var, value);
}
+   if (!strcmp(var, gc.prunereposexpire)) {
+   if (value  strcmp(value, now)) {
+   unsigned long now = approxidate(now);
+   if (approxidate(value) = now)
+   return error(_(Invalid %s: '%s'), var, value);
+   }
+   return git_config_string(prune_repos_expire, var, value);
+   }
return git_default_config(var, value, cb);
 }
 
@@ -274,6 +284,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
argv_array_pushl(reflog, reflog, expire, --all, NULL);
argv_array_pushl(repack, repack, -d, -l, NULL);
argv_array_pushl(prune, prune, --expire, NULL);
+   argv_array_pushl(prune_repos, prune, --repos, --expire, NULL);
argv_array_pushl(rerere, rerere, gc, NULL);
 
git_config(gc_config, NULL);
@@ -334,6 +345,12 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
return error(FAILED_RUN, prune.argv[0]);
}
 
+   if (prune_repos_expire) {
+   argv_array_push(prune_repos, prune_repos_expire);
+   if (run_command_v_opt(prune_repos.argv, RUN_GIT_CMD))
+   return error(FAILED_RUN, prune_repos.argv[0]);
+   }
+
if (run_command_v_opt(rerere.argv, RUN_GIT_CMD))
return error(FAILED_RUN, rerere.argv[0]);
 
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] branch: die when setting branch as own upstream

2014-03-01 Thread Brian Gesiak
Sorry for the multiple patches--I noticed the commit author was off in
the first one.

This patch converts the warning to an error, should it be decided that
it's prudent to do so (I'm in favor of doing so). If not, I think the
other two patches I submitted are good to merge.

Thanks for all the feedback so far!

- Brian Gesiak


On Sat, Mar 1, 2014 at 9:23 PM, Brian Gesiak modoca...@gmail.com wrote:
 Branch set as own upstream using one of the following commands returns
 immediately with an exit code of 0:

 - `git branch --set-upstream-to foo refs/heads/foo`
 - `git branch --force --track foo foo`

 Since neither of these actions currently set the upstream, an exit code
 of 0 is misleading. Instead, exit with a status code indicating failure
 by using the die function.

 Signed-off-by: Brian Gesiak modoca...@gmail.com
 ---
  branch.c  | 9 ++---
  t/t3200-branch.sh | 6 +++---
  2 files changed, 5 insertions(+), 10 deletions(-)

 diff --git a/branch.c b/branch.c
 index e163f3c..9bac8b5 100644
 --- a/branch.c
 +++ b/branch.c
 @@ -54,13 +54,8 @@ void install_branch_config(int flag, const char *local, 
 const char *origin, cons
 struct strbuf key = STRBUF_INIT;
 int rebasing = should_setup_rebase(origin);

 -   if (shortname
 -!strcmp(local, shortname)
 -!origin) {
 -   warning(_(Not setting branch %s as its own upstream.),
 -   local);
 -   return;
 -   }
 +   if (shortname  !strcmp(local, shortname)  !origin)
 +   die(_(Not setting branch %s as its own upstream.), local);

 strbuf_addf(key, branch.%s.remote, local);
 git_config_set(key.buf, origin ? origin : .);
 diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
 index 6164126..3ac493f 100755
 --- a/t/t3200-branch.sh
 +++ b/t/t3200-branch.sh
 @@ -507,10 +507,10 @@ EOF
 test_cmp expected actual
  '

 -test_expect_success '--set-upstream-to shows warning if used to set branch 
 as own upstream' '
 -   git branch --set-upstream-to refs/heads/my13 my13 2actual 
 +test_expect_success '--set-upstream-to fails if used to set branch as own 
 upstream' '
 +   test_must_fail git branch --set-upstream-to refs/heads/my13 my13 
 2actual 
 cat expected EOF 
 -warning: Not setting branch my13 as its own upstream.
 +fatal: Not setting branch my13 as its own upstream.
  EOF
 test_i18ncmp expected actual
  '
 --
 1.8.3.4 (Apple Git-47)

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] implemented strbuf_write_or_die()

2014-03-01 Thread He Sun
2014-03-01 19:21 GMT+08:00 Faiz Kothari faiz.of...@gmail.com:
 Signed-off-by: Faiz Kothari faiz.of...@gmail.com
 ---
 Implemented write_or_die.c:strbuf_write_or_die() and used in relevant places
 to substitute write_or_die(). I spotted other places where strbuf can be used
 in place of buf[MAX_PATH] but that would require a change in prototype of a
 lot of functions and functions calling them and so on
 I'll look for more places where strbuf can be used safely.

 Thanks.

  builtin/cat-file.c |2 +-
  builtin/notes.c|4 ++--
  builtin/receive-pack.c |2 +-
  builtin/send-pack.c|2 +-
  builtin/stripspace.c   |2 +-
  builtin/tag.c  |2 +-
  bundle.c   |2 +-
  cache.h|1 +
  credential-store.c |2 +-
  fetch-pack.c   |2 +-
  http-backend.c |2 +-
  remote-curl.c  |8 +---
  write_or_die.c |9 +
  13 files changed, 26 insertions(+), 14 deletions(-)

 diff --git a/builtin/cat-file.c b/builtin/cat-file.c
 index d5a93e0..c756cd5 100644
 --- a/builtin/cat-file.c
 +++ b/builtin/cat-file.c
 @@ -255,7 +255,7 @@ static int batch_one_object(const char *obj_name, struct 
 batch_options *opt,

 strbuf_expand(buf, opt-format, expand_format, data);
 strbuf_addch(buf, '\n');
 -   write_or_die(1, buf.buf, buf.len);
 +   strbuf_write_or_die(1, buf);
 strbuf_release(buf);

 if (opt-print_contents) {
 diff --git a/builtin/notes.c b/builtin/notes.c
 index 2b24d05..ef40183 100644
 --- a/builtin/notes.c
 +++ b/builtin/notes.c
 @@ -140,7 +140,7 @@ static void write_commented_object(int fd, const unsigned 
 char *object)
 if (strbuf_read(buf, show.out, 0)  0)
 die_errno(_(could not read 'show' output));
 strbuf_add_commented_lines(cbuf, buf.buf, buf.len);
 -   write_or_die(fd, cbuf.buf, cbuf.len);
 +   strbuf_write_or_die(fd, cbuf);

 strbuf_release(cbuf);
 strbuf_release(buf);
 @@ -174,7 +174,7 @@ static void create_note(const unsigned char *object, 
 struct msg_arg *msg,
 strbuf_addch(buf, '\n');
 strbuf_add_commented_lines(buf, note_template, 
 strlen(note_template));
 strbuf_addch(buf, '\n');
 -   write_or_die(fd, buf.buf, buf.len);
 +   strbuf_write_or_die(fd, buf);

 write_commented_object(fd, object);

 diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
 index 85bba35..9434516 100644
 --- a/builtin/receive-pack.c
 +++ b/builtin/receive-pack.c
 @@ -1114,7 +1114,7 @@ static void report(struct command *commands, const char 
 *unpack_status)
 if (use_sideband)
 send_sideband(1, 1, buf.buf, buf.len, use_sideband);
 else
 -   write_or_die(1, buf.buf, buf.len);
 +   strbuf_write_or_die(1, buf);
 strbuf_release(buf);
  }

 diff --git a/builtin/send-pack.c b/builtin/send-pack.c
 index f420b74..d053f0a 100644
 --- a/builtin/send-pack.c
 +++ b/builtin/send-pack.c
 @@ -86,7 +86,7 @@ static void print_helper_status(struct ref *ref)
 }
 strbuf_addch(buf, '\n');

 -   write_or_die(1, buf.buf, buf.len);
 +   strbuf_write_or_die(1, buf);
 }
 strbuf_release(buf);
  }
 diff --git a/builtin/stripspace.c b/builtin/stripspace.c
 index 1259ed7..cf5c876 100644
 --- a/builtin/stripspace.c
 +++ b/builtin/stripspace.c
 @@ -115,7 +115,7 @@ int cmd_stripspace(int argc, const char **argv, const 
 char *prefix)
 else
 comment_lines(buf);

 -   write_or_die(1, buf.buf, buf.len);
 +   strbuf_write_or_die(1, buf);
 strbuf_release(buf);
 return 0;
  }
 diff --git a/builtin/tag.c b/builtin/tag.c
 index 74d3780..5af6ea3 100644
 --- a/builtin/tag.c
 +++ b/builtin/tag.c
 @@ -349,7 +349,7 @@ static void create_tag(const unsigned char *object, const 
 char *tag,
 strbuf_commented_addf(buf, _(tag_template), 
 comment_line_char);
 else
 strbuf_commented_addf(buf, 
 _(tag_template_nocleanup), comment_line_char);
 -   write_or_die(fd, buf.buf, buf.len);
 +   strbuf_write_or_die(fd, buf);
 strbuf_release(buf);
 }
 close(fd);
 diff --git a/bundle.c b/bundle.c
 index e99065c..435505d 100644
 --- a/bundle.c
 +++ b/bundle.c
 @@ -279,7 +279,7 @@ int create_bundle(struct bundle_header *header, const 
 char *path,
 while (strbuf_getwholeline(buf, rls_fout, '\n') != EOF) {
 unsigned char sha1[20];
 if (buf.len  0  buf.buf[0] == '-') {
 -   write_or_die(bundle_fd, buf.buf, buf.len);
 +   strbuf_write_or_die(bundle_fd, buf);
 if (!get_sha1_hex(buf.buf + 1, sha1)) {
  

[PATCH] implemented strbuf_write_or_die()

2014-03-01 Thread Faiz Kothari
Signed-off-by: Faiz Kothari faiz.of...@gmail.com
---
  -   write_or_die(1, rpc.result.buf, rpc.result.len);
  +   strbuf_write_or_die(1, (rpc.result.buf));

 May be this should be
 strbuf_write_or_die(1, (rpc.result));

Yes, I changed that :-) Thanks again.

 Maybe we just call write_or_die() in strbuf_write_or_die(), in case that if we
 wanna change something in write_or_dir(), we don't have to do duplicate jobs.

Yes I changed it. It was unnecessary to reimplement it.

Thanks :)

 builtin/cat-file.c |2 +-
 builtin/notes.c|4 ++--
 builtin/receive-pack.c |2 +-
 builtin/send-pack.c|2 +-
 builtin/stripspace.c   |2 +-
 builtin/tag.c  |2 +-
 bundle.c   |2 +-
 cache.h|1 +
 credential-store.c |2 +-
 fetch-pack.c   |2 +-
 http-backend.c |2 +-
 remote-curl.c  |8 +---
 write_or_die.c |6 ++
 13 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index d5a93e0..c756cd5 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -255,7 +255,7 @@ static int batch_one_object(const char *obj_name, struct 
batch_options *opt,
 
strbuf_expand(buf, opt-format, expand_format, data);
strbuf_addch(buf, '\n');
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(1, buf);
strbuf_release(buf);
 
if (opt-print_contents) {
diff --git a/builtin/notes.c b/builtin/notes.c
index 2b24d05..ef40183 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -140,7 +140,7 @@ static void write_commented_object(int fd, const unsigned 
char *object)
if (strbuf_read(buf, show.out, 0)  0)
die_errno(_(could not read 'show' output));
strbuf_add_commented_lines(cbuf, buf.buf, buf.len);
-   write_or_die(fd, cbuf.buf, cbuf.len);
+   strbuf_write_or_die(fd, cbuf);
 
strbuf_release(cbuf);
strbuf_release(buf);
@@ -174,7 +174,7 @@ static void create_note(const unsigned char *object, struct 
msg_arg *msg,
strbuf_addch(buf, '\n');
strbuf_add_commented_lines(buf, note_template, 
strlen(note_template));
strbuf_addch(buf, '\n');
-   write_or_die(fd, buf.buf, buf.len);
+   strbuf_write_or_die(fd, buf);
 
write_commented_object(fd, object);
 
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 85bba35..9434516 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1114,7 +1114,7 @@ static void report(struct command *commands, const char 
*unpack_status)
if (use_sideband)
send_sideband(1, 1, buf.buf, buf.len, use_sideband);
else
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(1, buf);
strbuf_release(buf);
 }
 
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index f420b74..d053f0a 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -86,7 +86,7 @@ static void print_helper_status(struct ref *ref)
}
strbuf_addch(buf, '\n');
 
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(1, buf);
}
strbuf_release(buf);
 }
diff --git a/builtin/stripspace.c b/builtin/stripspace.c
index 1259ed7..cf5c876 100644
--- a/builtin/stripspace.c
+++ b/builtin/stripspace.c
@@ -115,7 +115,7 @@ int cmd_stripspace(int argc, const char **argv, const char 
*prefix)
else
comment_lines(buf);
 
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(1, buf);
strbuf_release(buf);
return 0;
 }
diff --git a/builtin/tag.c b/builtin/tag.c
index 74d3780..5af6ea3 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -349,7 +349,7 @@ static void create_tag(const unsigned char *object, const 
char *tag,
strbuf_commented_addf(buf, _(tag_template), 
comment_line_char);
else
strbuf_commented_addf(buf, 
_(tag_template_nocleanup), comment_line_char);
-   write_or_die(fd, buf.buf, buf.len);
+   strbuf_write_or_die(fd, buf);
strbuf_release(buf);
}
close(fd);
diff --git a/bundle.c b/bundle.c
index e99065c..435505d 100644
--- a/bundle.c
+++ b/bundle.c
@@ -279,7 +279,7 @@ int create_bundle(struct bundle_header *header, const char 
*path,
while (strbuf_getwholeline(buf, rls_fout, '\n') != EOF) {
unsigned char sha1[20];
if (buf.len  0  buf.buf[0] == '-') {
-   write_or_die(bundle_fd, buf.buf, buf.len);
+   strbuf_write_or_die(bundle_fd, buf);
if (!get_sha1_hex(buf.buf + 1, sha1)) {
struct object *object = 
parse_object_or_die(sha1, buf.buf);

[PATCH] git-compat-util.h:rewrite skip_prefix() as loop

2014-03-01 Thread Siddharth Goel
Rewrote skip_prefix() function so that prefix is scanned once.

Signed-off-by: Siddharth Goel siddharth98...@gmail.com
---
 git-compat-util.h | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/git-compat-util.h b/git-compat-util.h
index 614a5e9..550dce3 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -357,8 +357,11 @@ extern int suffixcmp(const char *str, const char *suffix);
 
 static inline const char *skip_prefix(const char *str, const char *prefix)
 {
-   size_t len = strlen(prefix);
-   return strncmp(str, prefix, len) ? NULL : str + len;
+   while (*prefix != '\0'  *str == *prefix) {
+   str++;
+   prefix++;
+   }
+   return (*prefix == '\0' ? str : NULL);
 }
 
 #if defined(NO_MMAP) || defined(USE_WIN32_MMAP)
-- 
1.9.0.138.g2de3478.dirty

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Replace memcpy with hashcpy when dealing hash copy globally

2014-03-01 Thread He Sun
2014-03-01 10:58 GMT+08:00 Duy Nguyen pclo...@gmail.com:
 On Sat, Mar 1, 2014 at 8:07 AM, Sun He sunheeh...@gmail.com wrote:
 Signed-off-by: Sun He sunheeh...@gmail.com
 ---
  Find the potential places with memcpy by the bash command:
$ find . | xargs grep memcpy.*\(.*20.*\)

  Helped-by: Michael Haggertymhag...@alum.mit.edu

 You may want to put this Helped-by before --- because it's supposed
 to end up in the final commit. The patch looks straightforward,
 except..


Yeah, got it.
Thanks.

 diff --git a/ppc/sha1.c b/ppc/sha1.c
 index ec6a192..8a87fea 100644
 --- a/ppc/sha1.c
 +++ b/ppc/sha1.c
 @@ -9,6 +9,7 @@
  #include stdio.h
  #include string.h
  #include sha1.h
 +#include cache.h

  extern void ppc_sha1_core(uint32_t *hash, const unsigned char *p,
   unsigned int nblocks);
 @@ -67,6 +68,6 @@ int ppc_SHA1_Final(unsigned char *hash, ppc_SHA_CTX *c)
 memset(c-buf.b[cnt], 0, 56 - cnt);
 c-buf.l[7] = c-len;
 ppc_sha1_core(c-hash, c-buf.b, 1);
 -   memcpy(hash, c-hash, 20);
 +   hashcpy(hash, c-hash);
 return 0;
  }

 cache.h (actually git-compat-util.h that cache.h includes) messes
 around with system headers by defining this and that macro. The
 general rule is if cache.h or git-compat-util.h is included, it's the
 first #include, and system includes will be always in
 git-compat-util.h (grep '^#include' shows this). Maybe it's best to
 leave this memcpy alone (and if you do, state so in the commit message
 with the reason).

Yap, after I parsed all the sourcecode

I have find out all the files that cache.h git-compat-util.h and
builtin.h are not the first #include

== test-sigchain.c ==
#include sigchain.h
== sigchain.c ==
#include sigchain.h

And I checked sigchain.h, that it includes very little information.
It didn't import any potential errors. But I think it should be placed
after cache.h to match the consistence of the general rule.

 --
 Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Replace memcpy with hashcpy when dealing hash copy globally

2014-03-01 Thread He Sun
2014-03-01 10:58 GMT+08:00 Duy Nguyen pclo...@gmail.com:
 On Sat, Mar 1, 2014 at 8:07 AM, Sun He sunheeh...@gmail.com wrote:
 Signed-off-by: Sun He sunheeh...@gmail.com
 ---
  Find the potential places with memcpy by the bash command:
$ find . | xargs grep memcpy.*\(.*20.*\)

  Helped-by: Michael Haggertymhag...@alum.mit.edu

 You may want to put this Helped-by before --- because it's supposed
 to end up in the final commit. The patch looks straightforward,
 except..


Yeah, got it.
Thanks.

 diff --git a/ppc/sha1.c b/ppc/sha1.c
 index ec6a192..8a87fea 100644
 --- a/ppc/sha1.c
 +++ b/ppc/sha1.c
 @@ -9,6 +9,7 @@
  #include stdio.h
  #include string.h
  #include sha1.h
 +#include cache.h

  extern void ppc_sha1_core(uint32_t *hash, const unsigned char *p,
   unsigned int nblocks);
 @@ -67,6 +68,6 @@ int ppc_SHA1_Final(unsigned char *hash, ppc_SHA_CTX *c)
 memset(c-buf.b[cnt], 0, 56 - cnt);
 c-buf.l[7] = c-len;
 ppc_sha1_core(c-hash, c-buf.b, 1);
 -   memcpy(hash, c-hash, 20);
 +   hashcpy(hash, c-hash);
 return 0;
  }

 cache.h (actually git-compat-util.h that cache.h includes) messes
 around with system headers by defining this and that macro. The
 general rule is if cache.h or git-compat-util.h is included, it's the
 first #include, and system includes will be always in
 git-compat-util.h (grep '^#include' shows this). Maybe it's best to
 leave this memcpy alone (and if you do, state so in the commit message
 with the reason).

Yap, I should follow the general rule. My fault.
Thanks.

What's more,

I have find out all the files that cache.h git-compat-util.h and
builtin.h are not the first #include

== test-sigchain.c ==
#include sigchain.h
== sigchain.c ==
#include sigchain.h

And I checked sigchain.h, that it includes very little information.
It didn't import any potential errors. But I think it should be placed
after cache.h to match the consistence of the general rule.

 --
 Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Replace memcpy with hashcpy when dealing hash copy globally

2014-03-01 Thread He Sun
Got it.
Thanks.

2014-03-01 17:13 GMT+08:00 Tay Ray Chuan rcta...@gmail.com:
 On Sat, Mar 1, 2014 at 10:58 AM, Duy Nguyen pclo...@gmail.com wrote:
 On Sat, Mar 1, 2014 at 8:07 AM, Sun He sunheeh...@gmail.com wrote:
 Signed-off-by: Sun He sunheeh...@gmail.com
 ---
  Find the potential places with memcpy by the bash command:
$ find . | xargs grep memcpy.*\(.*20.*\)

  Helped-by: Michael Haggertymhag...@alum.mit.edu

 You may want to put this Helped-by before --- because it's supposed
 to end up in the final commit.

 To elaborate further: anything below the three-dash is ignored when
 the patch is applied. So it doesn't show up in the commit at all. I
 don't really know the reason for this - probably a patch (1) thing.

 You could put the patch the Helped-by before your Signed-off-by
 (sometimes referred to as S-o-b).

 --
 Cheers,
 Ray Chuan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Place cache.h at the first place to match generl rule

2014-03-01 Thread Sun He
Signed-off-by: Sun He sunheeh...@gmail.com
Helped-by: Duy Nguyen pclo...@gmail.com
---

 The general rule is if cache.h or git-compat-util.h is included,
 it is the first #include.

 I parsed all the source files, and find many files start with builtin.h.
 And git-compat-util.h is the first in it. So they don't need any change.

 sigchain.c and test-sigchain.c are started with sigchain.h
 I checked sigchain.h, and it didn't import any bug.
 But to keep consistant with general rule, we should take this patch.

 Thanks.

 sigchain.c  | 2 +-
 test-sigchain.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/sigchain.c b/sigchain.c
index 1118b99..faa375d 100644
--- a/sigchain.c
+++ b/sigchain.c
@@ -1,5 +1,5 @@
-#include sigchain.h
 #include cache.h
+#include sigchain.h
 
 #define SIGCHAIN_MAX_SIGNALS 32
 
diff --git a/test-sigchain.c b/test-sigchain.c
index 42db234..e499fce 100644
--- a/test-sigchain.c
+++ b/test-sigchain.c
@@ -1,5 +1,5 @@
-#include sigchain.h
 #include cache.h
+#include sigchain.h
 
 #define X(f) \
 static void f(int sig) { \
-- 
1.9.0.138.g2de3478.dirty

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 13/27] git-stash: avoid hardcoding $GIT_DIR/logs/....

2014-03-01 Thread Torsten Bögershausen
On 2014-03-01 13.12, Nguyễn Thái Ngọc Duy wrote:
 Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
 ---
  git-stash.sh | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/git-stash.sh b/git-stash.sh
 index ae7d16e..12d9b37 100755
 --- a/git-stash.sh
 +++ b/git-stash.sh
 @@ -183,7 +183,7 @@ store_stash () {
   fi
  
   # Make sure the reflog for stash is kept.
 - : $GIT_DIR/logs/$ref_stash
 + : `git rev-parse --git-path logs/$ref_stash`
$(git rev-parse --git-path logs/$ref_stash)
Shouldn't we prefer $() over `` ?

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] contrib/subtree - unset prefix before proceeding

2014-03-01 Thread Gilles Filippini
This is to prevent unwanted prefix when such an environment variable
exists. The case occurs for example during the Debian package build
where the git-subtree test suite is called with 'prefix=/usr', which
makes test 21 fail:
not ok 21 - Check that prefix argument is required for split

Signed-off-by: Gilles Filippini gilles.filipp...@free.fr
---
 contrib/subtree/git-subtree.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index dc59a91..db925ca 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -46,6 +46,7 @@ ignore_joins=
 annotate=
 squash=
 message=
+prefix=
 
 debug()
 {
-- 
1.9.0



Re: [RFC 0/3] Make git more user-friendly during a merge conflict

2014-03-01 Thread Stephen Leake
Matthieu Moy matthieu@grenoble-inp.fr writes:

 $ git status
 On branch master
 nothing to commit, working directory clean
 $

ok, you've lost your conflict resolutions.

 In fact, it now seems that 'git reset --mixed' is always the same as
 'git reset --merge'. So I must be missing something!

 git reset --merge is an alias for git merge --abort (IIRC, it's
 actually the other way around). Essentially, it reverts, or tries to
 revert everything (worktree and index) as it was before the merge. That
 includes throwing away conflict resolution.

Ok.

 Now, I do agree that the documentation of git reset is terrible, 

Ok, good.

So is this a sufficient bug report to request that the documentation be
fixed? (I obviously don't know enough to even think about submitting a
patch).

-- 
-- Stephe
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 19/27] wrapper.c: wrapper to open a file, fprintf then close

2014-03-01 Thread Torsten Bögershausen
On 2014-03-01 13.12, Nguyễn Thái Ngọc Duy wrote:
 Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
 ---
  cache.h   |  2 ++
  wrapper.c | 31 +++
  2 files changed, 33 insertions(+)
 
 diff --git a/cache.h b/cache.h
 index 98b5dd3..99b86d9 100644
 --- a/cache.h
 +++ b/cache.h
 @@ -1239,6 +1239,8 @@ static inline ssize_t write_str_in_full(int fd, const 
 char *str)
  {
   return write_in_full(fd, str, strlen(str));
  }
 +__attribute__((format (printf,3,4)))
 +extern int write_file(const char *path, int fatal, const char *fmt, ...);
  
  /* pager.c */
  extern void setup_pager(void);
 diff --git a/wrapper.c b/wrapper.c
 index 0cc5636..5ced50d 100644
 --- a/wrapper.c
 +++ b/wrapper.c
 @@ -455,3 +455,34 @@ struct passwd *xgetpwuid_self(void)
   errno ? strerror(errno) : _(no such user));
   return pw;
  }
 +
 +int write_file(const char *path, int fatal, const char *fmt, ...)
 +{
 + struct strbuf sb = STRBUF_INIT;
 + int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0666);
 + va_list params;
 + if (fd  0) {
 + if (fatal)
 + die_errno(_(could not open %s for writing), path);
 + return -1;
 + }
 + va_start(params, fmt);
 + strbuf_vaddf(sb, fmt, params);
 + va_end(params);
 + if (write_in_full(fd, sb.buf, sb.len) != sb.len) {
 + int err = errno;
 + close(fd);
 + errno = err;
 + strbuf_release(sb);
Micro nit:
Today we now what strbuf_release() is doing, but if we ever change the
implementation, it is 3% safer to keep err a little bit longer like this:
 + strbuf_release(sb);
 + errno = err;

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 24/27] prune: strategies for linked checkouts

2014-03-01 Thread Torsten Bögershausen
On 2014-03-01 13.13, Nguyễn Thái Ngọc Duy wrote:
[]
  
 +static dev_t get_device_or_die(const char *path)
 +{
 + struct stat buf;
 + if (stat(path, buf))
 + die_errno(failed to stat '%s', path);
 + /* Ah Windows! Make different drives different partitions */
 + if (is_windows())
 + buf.st_dev = toupper(real_path(path)[0]);
 + return buf.st_dev;

Is this only related to Windows ?
Do we have other file systems, which return st_dev == 0 ?
Should we check that path[0] != '/', or better !is_dir_sep(path[0]) ?
Do we need has_dos_drive_prefix() ?

As a first suggestion, would this be better:

 + if (!buf.st_dev)
 + buf.st_dev = toupper(real_path(path)[0]);

(End of loose thinking)
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Place cache.h at the first place to match generl rule

2014-03-01 Thread brian m. carlson
On Sat, Mar 01, 2014 at 11:05:23PM +0800, Sun He wrote:
 Signed-off-by: Sun He sunheeh...@gmail.com
 Helped-by: Duy Nguyen pclo...@gmail.com

Your commit summary has generl instead of general.

-- 
brian m. carlson / brian with sandals: Houston, Texas, US
+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only
OpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187


signature.asc
Description: Digital signature


Re: Branch Name Case Sensitivity

2014-03-01 Thread Lee Hopkins
Incorporating Torsten suggestions and some documentation:

---
 Documentation/config.txt |   12 
 builtin/init-db.c|4 +++-
 config.c |5 +
 environment.c|1 +
 refs.c   |   26 +++---
 5 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 040197b..c0a6c5c 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2077,6 +2077,18 @@ receive.shallowupdate::
  If set to true, .git/shallow can be updated when new refs
  require new shallow roots. Otherwise those refs are rejected.

+refs.ignorecase::
+ If true, this option prevents the creation of ref names
+ that differ in case only. For example, if a branch Foo exists,
+ `git checkout -b foo` would fail. This is the case
+ across ref hierarchies, so `git tag foo` would also fail.
+ This option is useful on filesystems that are not case
+ sensitive.
++
+The default is false, except linkgit:git-clone[1] or linkgit:git-init[1]
+will probe and set refs.ignorecase true if appropriate when the repository
+is created. refs.ignorecase will also be true if core.ignorecase is true.
+
 remote.pushdefault::
  The remote to push to by default.  Overrides
  `branch.name.remote` for all branches, and is overridden by
diff --git a/builtin/init-db.c b/builtin/init-db.c
index c7c76bb..7c6931b 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -288,8 +288,10 @@ static int create_default_files(const char *template_path)
  /* Check if the filesystem is case-insensitive */
  path[len] = 0;
  strcpy(path + len, CoNfIg);
- if (!access(path, F_OK))
+ if (!access(path, F_OK)) {
  git_config_set(core.ignorecase, true);
+ git_config_set(refs.ignorecase, true);
+ }
  probe_utf8_pathname_composition(path, len);
  }

diff --git a/config.c b/config.c
index 314d8ee..797391a 100644
--- a/config.c
+++ b/config.c
@@ -702,6 +702,11 @@ static int git_default_core_config(const char
*var, const char *value)
  return 0;
  }

+ if (!strcmp(var, refs.ignorecase)) {
+ refs_ignore_case = git_config_bool(var, value);
+ return 0;
+ }
+
  if (!strcmp(var, core.attributesfile))
  return git_config_pathname(git_attributes_file, var, value);

diff --git a/environment.c b/environment.c
index 4a3437d..2eced48 100644
--- a/environment.c
+++ b/environment.c
@@ -18,6 +18,7 @@ int check_stat = 1;
 int has_symlinks = 1;
 int minimum_abbrev = 4, default_abbrev = 7;
 int ignore_case;
+int refs_ignore_case = -1;
 int assume_unchanged;
 int prefer_symlink_refs;
 int is_bare_repository_cfg = -1; /* unspecified */
diff --git a/refs.c b/refs.c
index 89228e2..1915ec2 100644
--- a/refs.c
+++ b/refs.c
@@ -359,16 +359,26 @@ struct string_slice {
  const char *str;
 };

-static int ref_entry_cmp_sslice(const void *key_, const void *ent_)
+static int ref_entry_ncmp(const void *key_, const void *ent_, int
(*cmp_fn)(const char *, const char *, size_t))
 {
  const struct string_slice *key = key_;
  const struct ref_entry *ent = *(const struct ref_entry * const *)ent_;
- int cmp = strncmp(key-str, ent-name, key-len);
+ int cmp = cmp_fn(key-str, ent-name, key-len);
  if (cmp)
  return cmp;
  return '\0' - (unsigned char)ent-name[key-len];
 }

+static int ref_entry_cmp_sslice(const void *key_, const void *ent_)
+{
+ return ref_entry_ncmp(key_, ent_, strncmp);
+}
+
+static int ref_entry_casecmp_sslice(const void *key_, const void *ent_)
+{
+ return ref_entry_ncmp(key_, ent_, strncasecmp);
+}
+
 /*
  * Return the index of the entry with the given refname from the
  * ref_dir (non-recursively), sorting dir if necessary.  Return -1 if
@@ -378,6 +388,7 @@ static int search_ref_dir(struct ref_dir *dir,
const char *refname, size_t len)
 {
  struct ref_entry **r;
  struct string_slice key;
+ int (*cmp_fn)(const void *, const void *);

  if (refname == NULL || !dir-nr)
  return -1;
@@ -385,8 +396,17 @@ static int search_ref_dir(struct ref_dir *dir,
const char *refname, size_t len)
  sort_ref_dir(dir);
  key.len = len;
  key.str = refname;
+
+ if(refs_ignore_case  0)
+ refs_ignore_case  = ignore_case;
+
+ if(ignore_case)
+ cmp_fn = ref_entry_casecmp_sslice;
+ else
+ cmp_fn = ref_entry_cmp_sslice;
+
  r = bsearch(key, dir-entries, dir-nr, sizeof(*dir-entries),
-ref_entry_cmp_sslice);
+ cmp_fn);

  if (r == NULL)
  return -1;
--
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] commit.c:record_author_date() use skip_prefix() instead of starts_with()

2014-03-01 Thread Tanay Abhra

Signed-off-by: Tanay Abhra tanay...@gmail.com
---
 commit.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/commit.c b/commit.c
index 6bf4fe0..c954ecb 100644
--- a/commit.c
+++ b/commit.c
@@ -566,7 +566,7 @@ static void record_author_date(struct author_date_slab 
*author_date,
 buf;
 buf = line_end + 1) {
line_end = strchrnul(buf, '\n');
-   if (!starts_with(buf, author )) {
+   if (!skip_prefix(buf, author )) {
if (!line_end[0] || line_end[1] == '\n')
return; /* end of header */
continue;
-- 
1.7.9.5

Hello,

This is my patch for the GSoC microproject #10:

Rewrite commit.c:record_author_date() to use skip_prefix(). 
Are there other places in this file where skip_prefix() would be more 
readable than starts_with()?

Since skip_prefix() and starts_with() implement the same functionality with 
different
return values, they can be interchanged easily.

Other usage of starts_with() in the same file can be found with

$ grep -n starts_with commit.c

1116:   else if (starts_with(line, gpg_sig_header) 
1196:   if (starts_with(buf, sigcheck_gpg_status[i].check + 1)) {

I have a query,should I tackle a bug from the mailing lists or research about 
the proposal 
and present a rough draft?

Cheers,
Tanay Abhra.


--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[GSoC14][RFC] Proposal Draft: Refactor tempfile handling

2014-03-01 Thread Brian Gesiak
Hello all,

My name is Brian Gesiak. I'm a research student at the University of
Tokyo, and I'm hoping to participate in this year's Google Summer of
Code by contributing to Git. I'm a longtime user, first-time
contributor--some of you may have noticed my microproject
patches.[1][2]

I'd like to gather some information on one of the GSoC ideas posted on
the ideas page. Namely, I'm interested in refactoring the way
tempfiles are cleaned up.

The ideas page points out that while lock files are closed and
unlinked[3] when the program exits[4], object pack files implement
their own brand of temp file creation and deletion. This
implementation doesn't share the same guarantees as lock files--it is
possible that the program terminates before the temp file is
unlinked.[5]

Lock file references are stored in a linked list. When the program
exits, this list is traversed and each file is closed and unlinked. It
seems to me that this mechanism is appropriate for temp files in
general, not just lock files. Thus, my proposal would be to extract
this logic into a separate module--tempfile.h, perhaps. Lock and
object files would share the tempfile implementation.

That is, both object and lock temp files would be stored in a linked
list, and all of these would be deleted at program exit.

I'm very enthused about this project--I think it has it all:

- Tangible benefits for the end-user
- Reduced complexity in the codebase
- Ambitious enough to be interesting
- Small enough to realistically be completed in a summer

Please let me know if this seems like it would make for an interesting
proposal, or if perhaps there is something I am overlooking. Any
feedback at all would be appreciated. Thank you!

- Brian Gesiak

[1] http://thread.gmane.org/gmane.comp.version-control.git/242891
[2] http://thread.gmane.org/gmane.comp.version-control.git/242893
[3] https://github.com/git/git/blob/v1.9.0/lockfile.c#L18
[4] https://github.com/git/git/blob/v1.9.0/lockfile.c#L143
[5] https://github.com/git/git/blob/v1.9.0/pack-write.c#L350
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] implemented strbuf_write_or_die()

2014-03-01 Thread Johannes Sixt
Am 01.03.2014 12:21, schrieb Faiz Kothari:
 Signed-off-by: Faiz Kothari faiz.of...@gmail.com
 ---
 Implemented write_or_die.c:strbuf_write_or_die() and used in relevant places
 to substitute write_or_die(). I spotted other places where strbuf can be used
 in place of buf[MAX_PATH] but that would require a change in prototype of a 
 lot of functions and functions calling them and so on
 I'll look for more places where strbuf can be used safely.

You haven't given a justifiction of the change (why is this change good?)

 diff --git a/write_or_die.c b/write_or_die.c
 index b50f99a..5fb309b 100644
 --- a/write_or_die.c
 +++ b/write_or_die.c
 @@ -1,4 +1,5 @@
  #include cache.h
 +#include strbuf.h

I think you have the layering backwards here: strbuf_write_or_die should
be part of the (higher-level) strbuf API, and not an extension of the
low-level write_or_die function.

  
  static void check_pipe(int err)
  {
 @@ -64,6 +65,14 @@ void write_or_die(int fd, const void *buf, size_t count)
   }
  }
  
 +void strbuf_write_or_die(int fd, const struct strbuf *sbuf)

And when you make the function a strbuf API, the prototype should be

void strbuf_write_or_die(const struct strbuf *sbuf, int fd)

as in hey, strbuf object, write your content to this file descriptor!

 +{
 + if(write_in_full(fd, sbuf-buf, sbuf-len)  0){
 + check_pipe(errno);
 + die_errno(write error);
 + }
 +}
 +
  int write_or_whine_pipe(int fd, const void *buf, size_t count, const char 
 *msg)
  {
   if (write_in_full(fd, buf, count)  0) {
 

-- Hannes

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] implemented strbuf_write_or_die()

2014-03-01 Thread Michael Haggerty
Please leave a little more time for people to give feedback between
versions of a patch series (unless the first version was so broken that
it would be pointless for any other reviewer to waste time on it.  And
please label the versions of a single patch series [PATCH] then
[PATCH v2], [PATCH v3], etc.

I agree with Johannes's advice that the function is in the wrong place
and has the wrong parameter order.

On 03/01/2014 02:29 PM, Faiz Kothari wrote:
 Signed-off-by: Faiz Kothari faiz.of...@gmail.com
 ---
 -   write_or_die(1, rpc.result.buf, rpc.result.len);
 +   strbuf_write_or_die(1, (rpc.result.buf));
 
 May be this should be
 strbuf_write_or_die(1, (rpc.result));
 
 Yes, I changed that :-) Thanks again.

I find it alarming that either the compiler didn't emit warnings for the
old version or that you ignored the compiler warnings.  Git should
compile without warnings even with with quite strict compiler settings;
I use gcc with the following options

-Wall -Werror \
-Wdeclaration-after-statement \
-Wno-format-zero-length \
-Wno-format-security

Maybe you weren't including the header file that declares
strbuf_write_or_die() in the file containing this invocation?

Also, the parentheses in (rpc.result) are unnecessary.

And I think that some of the blank lines that you added contained
invisible whitespace.  Please check your whitespace!  You can run git
diff --check to detect some obvious whitespace problems.

Michael

-- 
Michael Haggerty
mhag...@alum.mit.edu
http://softwareswirl.blogspot.com/
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH][GSoC] git-compat-util.h:rewrite skip_prefix() as loop

2014-03-01 Thread kgeorgiou
Rewritten git-compat-util.h:skip_prefix() as a loop, so that it doesn't have to
scan through the prefix string twice as a miniproject for GSoC 2014.

(I've just noticed that this miniproject has already been tackled by another 
contributor, if that's a problem I can pick something else.)

Looking forward to any kind of feedback.

- Kyriakos Georgiou

Signed-off-by: kgeorgiou kyriakos.a.georg...@gmail.com
---
 git-compat-util.h | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/git-compat-util.h b/git-compat-util.h
index 614a5e9..713f37a 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -357,8 +357,11 @@ extern int suffixcmp(const char *str, const char *suffix);
 
 static inline const char *skip_prefix(const char *str, const char *prefix)
 {
-   size_t len = strlen(prefix);
-   return strncmp(str, prefix, len) ? NULL : str + len;
+   while(*prefix  *str == *prefix) {
+   str++;
+   prefix++;
+   }
+   return *prefix ? NULL : str;
 }
 
 #if defined(NO_MMAP) || defined(USE_WIN32_MMAP)
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 24/27] prune: strategies for linked checkouts

2014-03-01 Thread Duy Nguyen
On Sun, Mar 2, 2014 at 12:12 AM, Torsten Bögershausen tbo...@web.de wrote:
 On 2014-03-01 13.13, Nguyễn Thái Ngọc Duy wrote:
 []

 +static dev_t get_device_or_die(const char *path)
 +{
 + struct stat buf;
 + if (stat(path, buf))
 + die_errno(failed to stat '%s', path);
 + /* Ah Windows! Make different drives different partitions */
 + if (is_windows())
 + buf.st_dev = toupper(real_path(path)[0]);
 + return buf.st_dev;

 Is this only related to Windows ?

Yes. At least the treatment is Windows specific. If st_dev == 0 in
other cases, then we have to deal with them case-by-case.

 Do we have other file systems, which return st_dev == 0 ?
 Should we check that path[0] != '/', or better !is_dir_sep(path[0]) ?
 Do we need has_dos_drive_prefix() ?

real_path() returns an absolute path, so we're guaranteed its first
character is the drive letter, right? (I tried to confirm this by
reading read_path_internal, but it's a bit complex, and I don't have
Windows machine to quickly test it out)


 As a first suggestion, would this be better:

 + if (!buf.st_dev)
 + buf.st_dev = toupper(real_path(path)[0]);

 (End of loose thinking)



-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] implemented strbuf_write_or_die()

2014-03-01 Thread Faiz Kothari
Signed-off-by: Faiz Kothari faiz.of...@gmail.com
---
Thanks for the feedback.
Implemented write_or_dir.c:strbuf_write_or_die() again.
Checks if NULL is passed to prevent segmentation fault, I was not sure 
what error message to print so for now its write error.
Changed the prototype as suggested.
Implementing this clearly distinguishes between writing a normal buffer
and writing a strbuf. Also, it provides an interface to write strbuf
directly without knowing the private members of strbuf, making strbuf 
completely opaque. Also, makes the code more readable.
I hope its proper now.

Thanks.

 builtin/cat-file.c |2 +-
 builtin/notes.c|6 +++---
 builtin/receive-pack.c |2 +-
 builtin/send-pack.c|2 +-
 builtin/stripspace.c   |2 +-
 builtin/tag.c  |2 +-
 bundle.c   |2 +-
 cache.h|1 +
 fetch-pack.c   |2 +-
 http-backend.c |2 +-
 remote-curl.c  |6 +++---
 write_or_die.c |   10 ++
 12 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index d5a93e0..d07a0be 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -255,7 +255,7 @@ static int batch_one_object(const char *obj_name, struct 
batch_options *opt,
 
strbuf_expand(buf, opt-format, expand_format, data);
strbuf_addch(buf, '\n');
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(buf, 1);
strbuf_release(buf);
 
if (opt-print_contents) {
diff --git a/builtin/notes.c b/builtin/notes.c
index 2b24d05..a208d56 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -140,7 +140,7 @@ static void write_commented_object(int fd, const unsigned 
char *object)
if (strbuf_read(buf, show.out, 0)  0)
die_errno(_(could not read 'show' output));
strbuf_add_commented_lines(cbuf, buf.buf, buf.len);
-   write_or_die(fd, cbuf.buf, cbuf.len);
+   strbuf_write_or_die(cbuf, fd);
 
strbuf_release(cbuf);
strbuf_release(buf);
@@ -167,14 +167,14 @@ static void create_note(const unsigned char *object, 
struct msg_arg *msg,
die_errno(_(could not create file '%s'), path);
 
if (msg-given)
-   write_or_die(fd, msg-buf.buf, msg-buf.len);
+   strbuf_write_or_die((msg-buf), fd);
else if (prev  !append_only)
write_note_data(fd, prev);
 
strbuf_addch(buf, '\n');
strbuf_add_commented_lines(buf, note_template, 
strlen(note_template));
strbuf_addch(buf, '\n');
-   write_or_die(fd, buf.buf, buf.len);
+   strbuf_write_or_die(buf, fd);
 
write_commented_object(fd, object);
 
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 85bba35..d590993 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1114,7 +1114,7 @@ static void report(struct command *commands, const char 
*unpack_status)
if (use_sideband)
send_sideband(1, 1, buf.buf, buf.len, use_sideband);
else
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(buf, 1);
strbuf_release(buf);
 }
 
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index f420b74..f26ba21 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -86,7 +86,7 @@ static void print_helper_status(struct ref *ref)
}
strbuf_addch(buf, '\n');
 
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(buf, 1);
}
strbuf_release(buf);
 }
diff --git a/builtin/stripspace.c b/builtin/stripspace.c
index 1259ed7..33b7f85 100644
--- a/builtin/stripspace.c
+++ b/builtin/stripspace.c
@@ -115,7 +115,7 @@ int cmd_stripspace(int argc, const char **argv, const char 
*prefix)
else
comment_lines(buf);
 
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(buf, 1);
strbuf_release(buf);
return 0;
 }
diff --git a/builtin/tag.c b/builtin/tag.c
index 74d3780..53ab280 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -349,7 +349,7 @@ static void create_tag(const unsigned char *object, const 
char *tag,
strbuf_commented_addf(buf, _(tag_template), 
comment_line_char);
else
strbuf_commented_addf(buf, 
_(tag_template_nocleanup), comment_line_char);
-   write_or_die(fd, buf.buf, buf.len);
+   strbuf_write_or_die(buf, fd);
strbuf_release(buf);
}
close(fd);
diff --git a/bundle.c b/bundle.c
index e99065c..c8bddd8 100644
--- a/bundle.c
+++ b/bundle.c
@@ -279,7 +279,7 @@ int create_bundle(struct bundle_header *header, const char 
*path,
while (strbuf_getwholeline(buf, rls_fout, '\n') 

Re: [BUG] Halt during fetch on MacOS

2014-03-01 Thread Kyle J. McKay

On Feb 28, 2014, at 22:15, Jeff King wrote:

On Fri, Feb 28, 2014 at 03:26:28PM -0800, Conley Owens wrote:


test.sh

#!/bin/bash
rungit() {
   mkdir $1
   GIT_DIR=$1 git init --bare
   echo '[remote aosp]'  $1/config
   echo 'url =
https://android.googlesource.com/platform/external/tinyxml2' 
$1/config
   GIT_DIR=$1 git fetch aosp +refs/heads/master:refs/remotes/aosp/ 
master


I don't think this is affecting your test, but you probably want  
 to

append to the config for the first line, too. Otherwise you are
overwriting some of git's default settings.


I replaced it with a call to git config in my version.

When everything cools, you can see that there are some fetches  
hanging

(typically).
$ ps | grep 'git fetch'
...
63310 ttys0040:00.01 git fetch aosp
+refs/heads/master:refs/remotes/aosp/master
[...]


I can't reproduce here on Linux. Can you find out what the processes  
are

doing with something like strace?


I can't reproduce, mostly, on Mac OS X 10.5.8 or 10.6.8.

What I mean by mostly is that the very first time I ran the test  
script I got approximately 36 of these errors:


fatal: unable to access 'https://android.googlesource.com/platform/external/tinyxml2/' 
: Unknown SSL protocol error in connection to android.googlesource.com: 
443


The rest of the fetches completed.  That was with Git 1.8.5.1.

However, I was never able to reproduce those errors again.  All the  
subsequent runs completed all fetches successfully using that same Git  
version so I also tried Git 1.8.5.2, 1.8.5.5 and Git 1.7.6.1 on the  
original and another machine.


I am, however NAT'd, so it's possible the NAT was somehow responsible  
for the initial 36 failures.


Perhaps you are seeing a similar issue.

You might try setting these sysctl variables:

# Timeout new TCP connections after 30 seconds instead of 75
net.inet.tcp.keepinit=3
# Always keep alive TCP connections
net.inet.tcp.always_keepalive=1
# Start keep alive checks after 30 seconds instead of 2 hours
net.inet.tcp.keepidle=3
# Wait 5 seconds between probes instead of 75
# Note that 8 probes in a row must fail to drop the connection
net.inet.tcp.keepintvl=5000

then running your test again and see if the hanging git fetch  
processes die with some kind of failed connection error within about  
70 seconds or so.  With the default sysctl settings, even with Git  
enabling keep alives, it would likely take a bit over two hours for a  
dead connection to be noticed.


--Kyle
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] Place cache.h at the first place to match general rule

2014-03-01 Thread Sun He
Signed-off-by: Sun He sunheeh...@gmail.com
Helped-by: Duy Nguyen pclo...@gmail.com
---

 PATCH v2 Fix the spelling bug of general in subject as is suggested
 by brain m.calson sand...@crustytoothpaste.net

 The general rule is if cache.h or git-compat-util.h is included,
 it is the first #include.

 I parsed all the source files, and find many files start with builtin.h.
 And git-compat-util.h is the first in it. So they don't need any change.

 sigchain.c and test-sigchain.c are started with sigchain.h
 I checked sigchain.h, and it didn't import any bug.
 But to keep consistant with general rule, we should take this patch.

 Thanks.

 sigchain.c  | 2 +-
 test-sigchain.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/sigchain.c b/sigchain.c
index 1118b99..faa375d 100644
--- a/sigchain.c
+++ b/sigchain.c
@@ -1,5 +1,5 @@
-#include sigchain.h
 #include cache.h
+#include sigchain.h
 
 #define SIGCHAIN_MAX_SIGNALS 32
 
diff --git a/test-sigchain.c b/test-sigchain.c
index 42db234..e499fce 100644
--- a/test-sigchain.c
+++ b/test-sigchain.c
@@ -1,5 +1,5 @@
-#include sigchain.h
 #include cache.h
+#include sigchain.h
 
 #define X(f) \
 static void f(int sig) { \
-- 
1.9.0.138.g2de3478.dirty

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] finish_tmp_packfile():use strbuf for pathname construction

2014-03-01 Thread Sun He
Signed-off-by: Sun He sunheeh...@gmail.com
Helped-by: Eric Sunshine sunsh...@sunshineco.com
Helped-by: Michael Haggerty mhag...@alum.mit.edu
---

This patch has assumed that you have already fix the bug of
tmpname in builtin/pack-objects.c:write_pack_file() warning()


 builtin/pack-objects.c | 15 ++-
 bulk-checkin.c |  8 +---
 pack-write.c   | 18 ++
 pack.h |  2 +-
 4 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index c733379..099d6ed 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -803,7 +803,7 @@ static void write_pack_file(void)
 
if (!pack_to_stdout) {
struct stat st;
-   char tmpname[PATH_MAX];
+   struct strbuf tmpname = STRBUF_INIT;
 
/*
 * Packs are runtime accessed in their mtime
@@ -826,23 +826,19 @@ static void write_pack_file(void)
tmpname, strerror(errno));
}
 
-   /* Enough space for -sha-1.pack? */
-   if (sizeof(tmpname) = strlen(base_name) + 50)
-   die(pack base name '%s' too long, base_name);
-   snprintf(tmpname, sizeof(tmpname), %s-, base_name);
+   strbuf_addf(tmpname, %s-, base_name);
 
if (write_bitmap_index) {
bitmap_writer_set_checksum(sha1);
bitmap_writer_build_type_index(written_list, 
nr_written);
}
 
-   finish_tmp_packfile(tmpname, pack_tmp_name,
+   finish_tmp_packfile(tmpname, pack_tmp_name,
written_list, nr_written,
pack_idx_opts, sha1);
 
if (write_bitmap_index) {
-   char *end_of_name_prefix = strrchr(tmpname, 0);
-   sprintf(end_of_name_prefix, %s.bitmap, 
sha1_to_hex(sha1));
+   strbuf_addf(tmpname, %s.bitmap 
,sha1_to_hex(sha1));
 
stop_progress(progress_state);
 
@@ -851,10 +847,11 @@ static void write_pack_file(void)
bitmap_writer_select_commits(indexed_commits, 
indexed_commits_nr, -1);
bitmap_writer_build(to_pack);
bitmap_writer_finish(written_list, nr_written,
-tmpname, 
write_bitmap_options);
+tmpname.buf, 
write_bitmap_options);
write_bitmap_index = 0;
}
 
+   strbuf_release(tmpname);
free(pack_tmp_name);
puts(sha1_to_hex(sha1));
}
diff --git a/bulk-checkin.c b/bulk-checkin.c
index 118c625..98e651c 100644
--- a/bulk-checkin.c
+++ b/bulk-checkin.c
@@ -4,6 +4,7 @@
 #include bulk-checkin.h
 #include csum-file.h
 #include pack.h
+#include strbuf.h
 
 static int pack_compression_level = Z_DEFAULT_COMPRESSION;
 
@@ -23,7 +24,7 @@ static struct bulk_checkin_state {
 static void finish_bulk_checkin(struct bulk_checkin_state *state)
 {
unsigned char sha1[20];
-   char packname[PATH_MAX];
+   struct strbuf packname = STRBUF_INIT;
int i;
 
if (!state-f)
@@ -43,8 +44,8 @@ static void finish_bulk_checkin(struct bulk_checkin_state 
*state)
close(fd);
}
 
-   sprintf(packname, %s/pack/pack-, get_object_directory());
-   finish_tmp_packfile(packname, state-pack_tmp_name,
+   strbuf_addf(packname, %s/pack/pack-, get_object_directory());
+   finish_tmp_packfile(packname, state-pack_tmp_name,
state-written, state-nr_written,
state-pack_idx_opts, sha1);
for (i = 0; i  state-nr_written; i++)
@@ -54,6 +55,7 @@ clear_exit:
free(state-written);
memset(state, 0, sizeof(*state));
 
+   strbuf_release(packname);
/* Make objects we just wrote available to ourselves */
reprepare_packed_git();
 }
diff --git a/pack-write.c b/pack-write.c
index 9b8308b..9ccf804 100644
--- a/pack-write.c
+++ b/pack-write.c
@@ -336,7 +336,7 @@ struct sha1file *create_tmp_packfile(char **pack_tmp_name)
return sha1fd(fd, *pack_tmp_name);
 }
 
-void finish_tmp_packfile(char *name_buffer,
+void finish_tmp_packfile(struct strbuf *name_buffer,
 const char *pack_tmp_name,
 struct pack_idx_entry **written_list,
 uint32_t nr_written,
@@ -344,7 +344,7 @@ void finish_tmp_packfile(char *name_buffer,

[PATCH v2] Replace tmpname with pack_tmp_name in warning. The developer mistook tmpname for pack_tmp_name.

2014-03-01 Thread Sun He
Signed-off-by: Sun He sunheeh...@gmail.com
---

 As tmpname is used without initialization, it should be a mistake.

 builtin/pack-objects.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index c733379..4922ce5 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -823,7 +823,7 @@ static void write_pack_file(void)
utb.modtime = --last_mtime;
if (utime(pack_tmp_name, utb)  0)
warning(failed utime() on %s: %s,
-   tmpname, strerror(errno));
+   pack_tmp_name, strerror(errno));
}
 
/* Enough space for -sha-1.pack? */
-- 
1.9.0.138.g2de3478.dirty

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] implemented strbuf_write_or_die()

2014-03-01 Thread Eric Sunshine
On Sat, Mar 1, 2014 at 7:18 PM, Faiz Kothari faiz.of...@gmail.com wrote:
 Subject: implemented strbuf_write_or_die()

Imperative tone is preferred. The commit message tells what it is
doing, not what it did.

  Subject: introduce strbuf_write_or_die()

 Signed-off-by: Faiz Kothari faiz.of...@gmail.com
 ---
 Implementing this clearly distinguishes between writing a normal buffer
 and writing a strbuf. Also, it provides an interface to write strbuf
 directly without knowing the private members of strbuf, making strbuf
 completely opaque. Also, makes the code more readable.

These three sentences which justify the change should go above the
--- line so they are recorded in the project history for future
readers to understand why the change was made. As for their actual
value, the first and third sentences are nebulous; the second sentence
may be suitable (although strbuf's buf and len are actually considered
public, so the justification not be supportable).

A couple other comments:

Justification is important because many topics are in-flight at any
given time. Changes like this one which touch an arbitrary number of
files may conflict with other in-flight topics, which places extra
burden on the project maintainer (Junio). The justification needs to
be strong enough to outweigh that added burden.

Introduction of a new function is conceptually distinct from the act
of updating existing callers to invoke it, thus this submission should
probably be decomposed into two or more patches where the first patch
introduces the function, and following patches convert existing
callers.

More below.

 diff --git a/cache.h b/cache.h
 index db223e8..8898bf4 100644
 --- a/cache.h
 +++ b/cache.h
 @@ -1227,6 +1227,7 @@ extern int copy_fd(int ifd, int ofd);
  extern int copy_file(const char *dst, const char *src, int mode);
  extern int copy_file_with_time(const char *dst, const char *src, int mode);
  extern void write_or_die(int fd, const void *buf, size_t count);
 +extern void strbuf_write_or_die(const struct strbuf *sbuf, int fd);

You still have the layering violation here mentioned by both Johannes
and Michael. This declaration belongs in strbuf.h, not cache.h

Also, for bonus points, you should document this new function in
Documentation/technical/api-strbuf.txt.

  extern int write_or_whine(int fd, const void *buf, size_t count, const char 
 *msg);
  extern int write_or_whine_pipe(int fd, const void *buf, size_t count, const 
 char *msg);
  extern void fsync_or_die(int fd, const char *);
 diff --git a/write_or_die.c b/write_or_die.c
 index b50f99a..373450e 100644
 --- a/write_or_die.c
 +++ b/write_or_die.c
 @@ -64,6 +64,16 @@ void write_or_die(int fd, const void *buf, size_t count)
 }
  }

 +void strbuf_write_or_die(const struct strbuf *sbuf, int fd)

Ditto regarding the layering violation. This implementation belongs in strbuf.c.

 +{
 +   if(!sbuf)
 +   fprintf(stderr, write error\n);

This is a programmer error, rather than a run-time I/O error. As such,
an assertion would be appropriate:

assert(sbuf);

 +   else if (write_in_full(fd, sbuf-buf, sbuf-len)  0) {
 +   check_pipe(errno);
 +   die_errno(write error);

He Sun correctly pointed out in his review that you should simply
invoke the lower-level write_or_die() here rather than copying/pasting
its functionality. (You fixed it in an earlier version of the patch
but somehow reverted that fix when sending this version.)

 +   }
 +}
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] rebase: new convenient option to edit a single commit

2014-03-01 Thread Nguyễn Thái Ngọc Duy
git rebase -e XYZ is basically the same as

EDITOR=sed -i '1s/pick XYZ/edit XYZ/' $@ \
git rebase -i XYZ^

In English, it prepares the todo list for you to edit only commit XYZ
to save your time. The time saving is only significant when you edit a
lot of commits separately.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/git-rebase.txt |  4 
 git-rebase--interactive.sh   | 17 ++---
 git-rebase.sh| 10 ++
 3 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 52c3561..b8c263d 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -359,6 +359,10 @@ unless the `--fork-point` option is specified.
user edit that list before rebasing.  This mode can also be used to
split commits (see SPLITTING COMMITS below).
 
+-e::
+--edit-one::
+   Prepare the todo list to edit only the commit at upstream
+
 -p::
 --preserve-merges::
Instead of ignoring merges, try to recreate them.
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index a1adae8..4762d57 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -1040,9 +1040,20 @@ fi
 has_action $todo ||
die_abort Nothing to do
 
-cp $todo $todo.backup
-git_sequence_editor $todo ||
-   die_abort Could not execute editor
+if test -n $edit_one
+then
+   edit_one=`git rev-parse --short $edit_one`
+   sed 1s/pick $edit_one /edit $edit_one / $todo  $todo.new ||
+   die_abort failed to update todo list
+   grep ^edit $edit_one  $todo.new /dev/null ||
+   die_abort expected to find 'edit $edit_one' line but did not
+   mv $todo.new $todo ||
+   die_abort failed to update todo list
+else
+   cp $todo $todo.backup
+   git_sequence_editor $todo ||
+   die_abort Could not execute editor
+fi
 
 has_action $todo ||
die_abort Nothing to do
diff --git a/git-rebase.sh b/git-rebase.sh
index 33face1..b8b6aa9 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -32,6 +32,7 @@ verify allow pre-rebase hook to run
 rerere-autoupdate  allow rerere to update index with resolved conflicts
 root!  rebase all reachable commits up to the root(s)
 autosquash move commits that begin with squash!/fixup! under -i
+e,edit-one!generate todo list to edit this commit
 committer-date-is-author-date! passed to 'git am'
 ignore-date!   passed to 'git am'
 whitespace=!   passed to 'git apply'
@@ -339,6 +340,10 @@ do
-NUM=*)
NUM=${1#-NUM=}
;;
+   --edit-one)
+   interactive_rebase=explicit
+   edit_one=t
+   ;;
--)
shift
break
@@ -463,6 +468,11 @@ then
;;
*)  upstream_name=$1
shift
+   if test -n $edit_one
+   then
+   edit_one=$upstream_name
+   upstream_name=$upstream_name^
+   fi
;;
esac
upstream=$(peel_committish ${upstream_name}) ||
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] rebase's convenient options

2014-03-01 Thread Nguyễn Thái Ngọc Duy
A polished version from the RFC. Now you can do

git rebase -i -10 - git rebase -i HEAD~10
git rebase -e XYZ - send you to commit XYZ for editing

Nguyễn Thái Ngọc Duy (3):
  rev-parse: support OPT_NUMBER_CALLBACK in --parseopt
  rebase: accept -number as another way of saying HEAD~number
  rebase: new convenient option to edit a single commit

 Documentation/git-rebase.txt |  7 +++
 builtin/rev-parse.c  |  9 +++--
 git-rebase--interactive.sh   | 17 ++---
 git-rebase.sh| 19 +++
 t/t3400-rebase.sh|  6 ++
 5 files changed, 53 insertions(+), 5 deletions(-)

-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] rebase: accept -number as another way of saying HEAD~number

2014-03-01 Thread Nguyễn Thái Ngọc Duy
This is rev-list style, where people can do git rev-list -3 in
addition to git rev-list HEAD~3. A lot of commands are driven by the
revision machinery and also accept this form. This addition to rebase
is just for convenience.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/git-rebase.txt | 3 +++
 git-rebase.sh| 9 +
 t/t3400-rebase.sh| 6 ++
 3 files changed, 18 insertions(+)

diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 2a93c64..52c3561 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -223,6 +223,9 @@ As a special case, you may use A\...B as a shortcut for 
the
 merge base of A and B if there is exactly one merge base. You can
 leave out at most one of A and B, in which case it defaults to HEAD.
 
+-number::
+   Specify upstream as HEAD~number.
+
 upstream::
Upstream branch to compare against.  May be any valid commit,
not just an existing branch name. Defaults to the configured
diff --git a/git-rebase.sh b/git-rebase.sh
index 5f6732b..33face1 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -43,6 +43,7 @@ continue!  continue
 abort! abort and check out the original branch
 skip!  skip current patch and continue
 edit-todo! edit the todo list during an interactive rebase
+-NUM   equivalent of HEAD~NUM
 
 . git-sh-setup
 . git-sh-i18n
@@ -335,6 +336,9 @@ do
--gpg-sign=*)
gpg_sign_opt=-S${1#--gpg-sign=}
;;
+   -NUM=*)
+   NUM=${1#-NUM=}
+   ;;
--)
shift
break
@@ -342,6 +346,11 @@ do
esac
shift
 done
+if [ -n $NUM ]
+then
+   test $# -gt 0  usage
+   set -- $@ HEAD~$NUM
+fi
 test $# -gt 2  usage
 
 if test -n $cmd 
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index 6d94b1f..11db7ea 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -215,4 +215,10 @@ test_expect_success 'rebase commit with an ancient 
timestamp' '
grep author .* 34567 +0600$ actual
 '
 
+test_expect_success 'rebase -number' '
+   git reset --hard 
+   test_must_fail git rebase -2 HEAD^^ 
+   git rebase -2
+'
+
 test_done
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] rev-parse: support OPT_NUMBER_CALLBACK in --parseopt

2014-03-01 Thread Nguyễn Thái Ngọc Duy
If the option spec is

-NUM Help string

then rev-parse will accept and parse -([0-9]+) and return -NUM $1

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/rev-parse.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 45901df..b37676f 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -331,6 +331,8 @@ static int parseopt_dump(const struct option *o, const char 
*arg, int unset)
struct strbuf *parsed = o-value;
if (unset)
strbuf_addf(parsed,  --no-%s, o-long_name);
+   else if (o-type == OPTION_NUMBER)
+   strbuf_addf(parsed,  -NUM);
else if (o-short_name  (o-long_name == NULL || !stuck_long))
strbuf_addf(parsed,  -%c, o-short_name);
else
@@ -338,7 +340,7 @@ static int parseopt_dump(const struct option *o, const char 
*arg, int unset)
if (arg) {
if (!stuck_long)
strbuf_addch(parsed, ' ');
-   else if (o-long_name)
+   else if (o-long_name || o-type == OPTION_NUMBER)
strbuf_addch(parsed, '=');
sq_quote_buf(parsed, arg);
}
@@ -439,7 +441,10 @@ static int cmd_parseopt(int argc, const char **argv, const 
char *prefix)
 
if (s - sb.buf == 1) /* short option only */
o-short_name = *sb.buf;
-   else if (sb.buf[1] != ',') /* long option only */
+   else if (s - sb.buf == 4  !strncmp(sb.buf, -NUM, 4)) {
+   o-type = OPTION_NUMBER;
+   o-flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG;
+   } else if (sb.buf[1] != ',') /* long option only */
o-long_name = xmemdupz(sb.buf, s - sb.buf);
else {
o-short_name = *sb.buf;
-- 
1.9.0.40.gaa8c3ea

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] implemented strbuf_write_or_die()

2014-03-01 Thread Eric Sunshine
On Sat, Mar 1, 2014 at 9:47 PM, Eric Sunshine sunsh...@sunshineco.com wrote:
 On Sat, Mar 1, 2014 at 7:18 PM, Faiz Kothari faiz.of...@gmail.com wrote:
 Implementing this clearly distinguishes between writing a normal buffer
 and writing a strbuf. Also, it provides an interface to write strbuf
 directly without knowing the private members of strbuf, making strbuf
 completely opaque. Also, makes the code more readable.

 These three sentences which justify the change should go above the
 --- line so they are recorded in the project history for future
 readers to understand why the change was made. As for their actual
 value, the first and third sentences are nebulous; the second sentence
 may be suitable (although strbuf's buf and len are actually considered
 public, so the justification not be supportable).

...justification *may* not be...
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] implemented strbuf_write_or_die()

2014-03-01 Thread Eric Sunshine
On Sat, Mar 1, 2014 at 7:51 AM, He Sun sunheeh...@gmail.com wrote:
 2014-03-01 19:21 GMT+08:00 Faiz Kothari faiz.of...@gmail.com:
 diff --git a/remote-curl.c b/remote-curl.c
 index 10cb011..dee8716 100644
 --- a/remote-curl.c
 +++ b/remote-curl.c
 @@ -634,7 +634,7 @@ static int rpc_service(struct rpc_state *rpc, struct 
 discovery *heads)
 if (start_command(client))
 exit(1);
 if (preamble)
 -   write_or_die(client.in, preamble-buf, preamble-len);
 +   strbuf_write_or_die(client.in, preamble);
 if (heads)
 write_or_die(client.in, heads-buf, heads-len);

 This should be changed. May be you can use Ctrl-F to search write_or_die().
 Or if you are using vim, use / and n to find all.

It's not obvious from the patch fragment, but 'heads' is not a strbuf,
so Faiz correctly left this invocation alone.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] git-compat-util.h:rewrite skip_prefix() as loop

2014-03-01 Thread Siddharth Goel
To my surprise, git format-patch had removed the Git Notes that I had
put to my commit (regarding GSoC). I have written this patch as a part
of the GSoC 2014 MicroProject for Git. Going through the mail-chain I
observed that many students have attempted this Microproject. So is it
ok if I stick to this Microproject or should I go with another one?

On Sat, Mar 1, 2014 at 9:32 PM, Siddharth Goel siddharth98...@gmail.com wrote:
 Rewrote skip_prefix() function so that prefix is scanned once.

 Signed-off-by: Siddharth Goel siddharth98...@gmail.com
 ---
  git-compat-util.h | 7 +--
  1 file changed, 5 insertions(+), 2 deletions(-)

 diff --git a/git-compat-util.h b/git-compat-util.h
 index 614a5e9..550dce3 100644
 --- a/git-compat-util.h
 +++ b/git-compat-util.h
 @@ -357,8 +357,11 @@ extern int suffixcmp(const char *str, const char 
 *suffix);

  static inline const char *skip_prefix(const char *str, const char *prefix)
  {
 -   size_t len = strlen(prefix);
 -   return strncmp(str, prefix, len) ? NULL : str + len;
 +   while (*prefix != '\0'  *str == *prefix) {
 +   str++;
 +   prefix++;
 +   }
 +   return (*prefix == '\0' ? str : NULL);
  }

  #if defined(NO_MMAP) || defined(USE_WIN32_MMAP)
 --
 1.9.0.138.g2de3478.dirty

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


hello

2014-03-01 Thread Sandra Hassan


HelloMy name is Miss Sandra Hassan I saw your profile today and ibecame 
interested in you, I will also want to know you moreand I want you to send an 
email to my mailbox so  that I can give you my pictureyours new friend.Sandra

مرحبااسمي ملكة جمال ساندرا حسن رأيت بروفايلك اليوم وأناأصبحت مهتمة لكم، وأنا 
أريد أيضا أن أعرف المزيد عنكوأنا أريد منك أن إرسال بريد إلكتروني إلى صندوق 
البريد الخاص بي حتى أستطيع أن أعطيك صورة بلديلك صديق جديد.ساندرا

Re: [PATCH v2] Replace tmpname with pack_tmp_name in warning. The developer mistook tmpname for pack_tmp_name.

2014-03-01 Thread Eric Sunshine
On Sat, Mar 1, 2014 at 9:43 PM, Sun He sunheeh...@gmail.com wrote:
 Subject: Replace tmpname with pack_tmp_name in warning. The developer mistook 
 tmpname for pack_tmp_name.

The subject should be a short summary of the change, and the rest of
the commit message before the --- line provides extra detail
explaining the change.

 Signed-off-by: Sun He sunheeh...@gmail.com
 ---

  As tmpname is used without initialization, it should be a mistake.

This is valid information for the commit message above the --- line.
So, your full commit message might say something like this:

Subject: write_pack_file: use correct variable in diagnostic

'pack_tmp_name' is the subject of the utime() check, so report
it in the warning, not the uninitialized 'tmpname'.

  builtin/pack-objects.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

 diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
 index c733379..4922ce5 100644
 --- a/builtin/pack-objects.c
 +++ b/builtin/pack-objects.c
 @@ -823,7 +823,7 @@ static void write_pack_file(void)
 utb.modtime = --last_mtime;
 if (utime(pack_tmp_name, utb)  0)
 warning(failed utime() on %s: %s,
 -   tmpname, strerror(errno));
 +   pack_tmp_name, 
 strerror(errno));
 }

 /* Enough space for -sha-1.pack? */
 --
 1.9.0.138.g2de3478.dirty
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] Place cache.h at the first place to match general rule

2014-03-01 Thread Eric Sunshine
On Sat, Mar 1, 2014 at 9:18 PM, Sun He sunheeh...@gmail.com wrote:
 Signed-off-by: Sun He sunheeh...@gmail.com
 Helped-by: Duy Nguyen pclo...@gmail.com

Footers should follow a temporal order. For instance:

1. Duy helped you.
2. You revised your patch based upon his input.
3. You signed off before submitting the patch.

Hence, your Signed-off-by: should follow Helped-by:.

 ---
  PATCH v2 Fix the spelling bug of general in subject as is suggested
  by brain m.calson sand...@crustytoothpaste.net

There are two type of information you want to convey to readers:

1. Explanation and justification of the change itself. This is
recorded for all time in the project history as the commit message. It
is placed above the --- line.

2. Commentary related to this version / submission of the patch which
is not likely to be helpful or meaningful to people reading the
official project history via the commit messages. It is placed below
the --- line.

Explaining what you changed since the previous version of the patch,
as you do above, is a good thing. It's not meaningful once the patch
is officially accepted into the project; it's only meaningful to
people following the progression of the patch on the mailing list, so
it definitely belongs below the --- line, as you did here.

However...

  The general rule is if cache.h or git-compat-util.h is included,
  it is the first #include.

This information explains the patch's purpose, thus it is relevant to
the project history. It belongs above the --- line.

  I parsed all the source files, and find many files start with builtin.h.
  And git-compat-util.h is the first in it. So they don't need any change.

This could go either way. It tells how you arrived at this version of
the patch (relevant below ---), but also explains why the patch does
not have to touch additional files (relevant above ---). It's
probably okay to leave it below ---.

  sigchain.c and test-sigchain.c are started with sigchain.h
  I checked sigchain.h, and it didn't import any bug.
  But to keep consistant with general rule, we should take this patch.

Commentary suitable for below ---.

  Thanks.

  sigchain.c  | 2 +-
  test-sigchain.c | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)

 diff --git a/sigchain.c b/sigchain.c
 index 1118b99..faa375d 100644
 --- a/sigchain.c
 +++ b/sigchain.c
 @@ -1,5 +1,5 @@
 -#include sigchain.h
  #include cache.h
 +#include sigchain.h

  #define SIGCHAIN_MAX_SIGNALS 32

 diff --git a/test-sigchain.c b/test-sigchain.c
 index 42db234..e499fce 100644
 --- a/test-sigchain.c
 +++ b/test-sigchain.c
 @@ -1,5 +1,5 @@
 -#include sigchain.h
  #include cache.h
 +#include sigchain.h

  #define X(f) \
  static void f(int sig) { \
 --
 1.9.0.138.g2de3478.dirty
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH][GSoC] git-compat-util.h:rewrite skip_prefix() as loop

2014-03-01 Thread Eric Sunshine
Thanks for the submission. Minor comments below to give you a taste of
what it's like to contribute to this project...

On Sat, Mar 1, 2014 at 5:42 PM, kgeorgiou kyriakos.a.georg...@gmail.com wrote:
 Subject: git-compat-util.h:rewrite skip_prefix() as loop

Space after colon. You might be able to provide more information in
the short summary of the subject. Perhaps something like this:

Subject: skip_prefix(): avoid scanning 'prefix' twice

 Rewritten git-compat-util.h:skip_prefix() as a loop, so that it doesn't have 
 to
 scan through the prefix string twice as a miniproject for GSoC 2014.

Good description. In this project, use imperative tone:

Rewrite skip_prefix() as loop...

 (I've just noticed that this miniproject has already been tackled by another
 contributor, if that's a problem I can pick something else.)

That's okay. The purpose of the miniprojects is for you to get a taste
of what it's like to contribute to this project and to understand what
will be expected of you as a GSoC student; and to give the GSoC
mentors a chance to judge your abilities and observe how you interact
with reviewers.

 Looking forward to any kind of feedback.

 - Kyriakos Georgiou

There are two types of information you want to convey to readers. (1)
Patch description, explanation, justification before the --- line
which is recorded in the permanent project history. (2) Commentary
below the --- line for readers of the patch but not of interest once
the patch is accepted officially. The as a miniproject for GSoC and
all lines following it are just commentary which should go below the
--- line.

 Signed-off-by: kgeorgiou kyriakos.a.georg...@gmail.com

This project prefers real names, so:

Signed-off-by: Kyriakos Georgiou ...

 ---
  git-compat-util.h | 7 +--
  1 file changed, 5 insertions(+), 2 deletions(-)

 diff --git a/git-compat-util.h b/git-compat-util.h
 index 614a5e9..713f37a 100644
 --- a/git-compat-util.h
 +++ b/git-compat-util.h
 @@ -357,8 +357,11 @@ extern int suffixcmp(const char *str, const char 
 *suffix);

  static inline const char *skip_prefix(const char *str, const char *prefix)
  {
 -   size_t len = strlen(prefix);
 -   return strncmp(str, prefix, len) ? NULL : str + len;
 +   while(*prefix  *str == *prefix) {

Style nit: space after 'while'.

 +   str++;
 +   prefix++;
 +   }
 +   return *prefix ? NULL : str;
  }

  #if defined(NO_MMAP) || defined(USE_WIN32_MMAP)
 --
 1.8.3.2
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] git-compat-util.h:rewrite skip_prefix() as loop

2014-03-01 Thread Eric Sunshine
Thanks for the submission. Minor comments below to give you a taste of
what it's like to contribute to this project...

On Sat, Mar 1, 2014 at 8:32 AM, Siddharth Goel siddharth98...@gmail.com wrote:
 Rewrote skip_prefix() function so that prefix is scanned once.

Good description. In this project, use imperative tone, so say
Rewrite skip_prefix()... as you did in the subject. In fact, this
description is short enough and conveys sufficient information that it
could just be placed in the subject as the entire commit message.

Subject: skip_prefix: rewrite so that prefix is scanned once

 Signed-off-by: Siddharth Goel siddharth98...@gmail.com
 ---
  git-compat-util.h | 7 +--
  1 file changed, 5 insertions(+), 2 deletions(-)

 diff --git a/git-compat-util.h b/git-compat-util.h
 index 614a5e9..550dce3 100644
 --- a/git-compat-util.h
 +++ b/git-compat-util.h
 @@ -357,8 +357,11 @@ extern int suffixcmp(const char *str, const char 
 *suffix);

  static inline const char *skip_prefix(const char *str, const char *prefix)
  {
 -   size_t len = strlen(prefix);
 -   return strncmp(str, prefix, len) ? NULL : str + len;
 +   while (*prefix != '\0'  *str == *prefix) {
 +   str++;
 +   prefix++;
 +   }
 +   return (*prefix == '\0' ? str : NULL);
  }

  #if defined(NO_MMAP) || defined(USE_WIN32_MMAP)
 --
 1.9.0.138.g2de3478.dirty
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] git-compat-util.h:rewrite skip_prefix() as loop

2014-03-01 Thread Eric Sunshine
On Sat, Mar 1, 2014 at 10:22 PM, Siddharth Goel
siddharth98...@gmail.com wrote:
 To my surprise, git format-patch had removed the Git Notes that I had
 put to my commit (regarding GSoC). I have written this patch as a part
 of the GSoC 2014 MicroProject for Git.

You probably wanted to use the --notes option with format-patch.

 Going through the mail-chain I
 observed that many students have attempted this Microproject. So is it
 ok if I stick to this Microproject or should I go with another one?

That's okay. The purpose of the miniprojects is for you to get a taste
of what it's like to contribute to this project and to understand what
will be expected of you as a GSoC student; and to give the GSoC
mentors a chance to judge your abilities and observe how you interact
with reviewers.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] Replace tmpname with pack_tmp_name in warning. The developer mistook tmpname for pack_tmp_name.

2014-03-01 Thread He Sun
2014-03-02 11:59 GMT+08:00 Eric Sunshine sunsh...@sunshineco.com:
 On Sat, Mar 1, 2014 at 9:43 PM, Sun He sunheeh...@gmail.com wrote:
 Subject: Replace tmpname with pack_tmp_name in warning. The developer 
 mistook tmpname for pack_tmp_name.

 The subject should be a short summary of the change, and the rest of
 the commit message before the --- line provides extra detail
 explaining the change.


OK, got it.
Thank you very much.

 Signed-off-by: Sun He sunheeh...@gmail.com
 ---

  As tmpname is used without initialization, it should be a mistake.

 This is valid information for the commit message above the --- line.
 So, your full commit message might say something like this:

 Subject: write_pack_file: use correct variable in diagnostic

 'pack_tmp_name' is the subject of the utime() check, so report
 it in the warning, not the uninitialized 'tmpname'.


Thank you for your suggestion, I will modify it right now. :-)

  builtin/pack-objects.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

 diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
 index c733379..4922ce5 100644
 --- a/builtin/pack-objects.c
 +++ b/builtin/pack-objects.c
 @@ -823,7 +823,7 @@ static void write_pack_file(void)
 utb.modtime = --last_mtime;
 if (utime(pack_tmp_name, utb)  0)
 warning(failed utime() on %s: %s,
 -   tmpname, strerror(errno));
 +   pack_tmp_name, 
 strerror(errno));
 }

 /* Enough space for -sha-1.pack? */
 --
 1.9.0.138.g2de3478.dirty
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3] write_pack_file: use correct variable in diagnostic

2014-03-01 Thread Sun He
'pack_tmp_name' is the subject of the utime() check, so report it in the
warning, not the uninitialized 'tmpname'

Signed-off-by: Sun He sunheeh...@gmail.com
---

 Changing the subject and adding valid information as tutored by 
 Eric Sunshine.
 Thanks to him.

 builtin/pack-objects.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index c733379..4922ce5 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -823,7 +823,7 @@ static void write_pack_file(void)
utb.modtime = --last_mtime;
if (utime(pack_tmp_name, utb)  0)
warning(failed utime() on %s: %s,
-   tmpname, strerror(errno));
+   pack_tmp_name, strerror(errno));
}
 
/* Enough space for -sha-1.pack? */
-- 
1.9.0.138.g2de3478.dirty

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/2] Introduce strbuf_write_or_die()

2014-03-01 Thread Faiz Kothari
Signed-off-by: Faiz Kothari faiz.of...@gmail.com

Introduced a new function strbuf.c:strbuf_write_or_die()
to the strbuf family of functions. Now use this API instead
of write_or_die.c:write_or_die()
---
Hi,
Thanks for the suggestions and feedbacks.
As Johannes Sixt  pointed out, the function is now defined
in strbuf.c and prototype added to strbuf.h
Also, replaced if(!sbuf) with assert(sbuf) and split the patch into two 
as pointed out by Eric Sunshine.

As far as justification is concerned, I am not able to come up with
a satisfactory justification. Apart from, that it makes life of the
programmer a little easier and if we add a few more functions
to thestrbuf API, we can make strbuf completely opaque. I am open
to views and since I haven't used this API extensively, I cannot
comment for what is missing and what is required. But I am going through it.
Also, once this patch is OK, I'll add documentation for the API.

Thanks again for the feedback.

 strbuf.c |6 ++
 strbuf.h |1 +
 2 files changed, 7 insertions(+)

diff --git a/strbuf.c b/strbuf.c
index 83caf4a..337a70c 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -477,6 +477,12 @@ int strbuf_read_file(struct strbuf *sb, const char *path, 
size_t hint)
return len;
 }
 
+void strbuf_write_or_die(const struct strbuf *sb, int fd)
+{
+   assert(sb);
+   write_or_die(fd, sb-buf, sb-len);
+}
+
 void strbuf_add_lines(struct strbuf *out, const char *prefix,
  const char *buf, size_t size)
 {
diff --git a/strbuf.h b/strbuf.h
index 73e80ce..6aadb6d 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -156,6 +156,7 @@ extern size_t strbuf_fread(struct strbuf *, size_t, FILE *);
 /* XXX: if read fails, any partial read is undone */
 extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint);
 extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
+extern void strbuf_write_or_die(const struct strbuf *sb, int fd);
 extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
 
 extern int strbuf_getwholeline(struct strbuf *, FILE *, int);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 2/2] use strbuf_write_or_die()

2014-03-01 Thread Faiz Kothari
Signed-off-by: Faiz Kothari faiz.of...@gmail.com

Used strbuf.c:strbuf_write_or_die() instead of
write_or_die.c:write_or_die() at relevant places.
---
 builtin/cat-file.c |2 +-
 builtin/notes.c|6 +++---
 builtin/receive-pack.c |2 +-
 builtin/send-pack.c|2 +-
 builtin/stripspace.c   |2 +-
 builtin/tag.c  |2 +-
 bundle.c   |2 +-
 credential-store.c |2 +-
 fetch-pack.c   |2 +-
 http-backend.c |2 +-
 remote-curl.c  |6 +++---
 11 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index d5a93e0..d07a0be 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -255,7 +255,7 @@ static int batch_one_object(const char *obj_name, struct 
batch_options *opt,
 
strbuf_expand(buf, opt-format, expand_format, data);
strbuf_addch(buf, '\n');
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(buf, 1);
strbuf_release(buf);
 
if (opt-print_contents) {
diff --git a/builtin/notes.c b/builtin/notes.c
index 2b24d05..a208d56 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -140,7 +140,7 @@ static void write_commented_object(int fd, const unsigned 
char *object)
if (strbuf_read(buf, show.out, 0)  0)
die_errno(_(could not read 'show' output));
strbuf_add_commented_lines(cbuf, buf.buf, buf.len);
-   write_or_die(fd, cbuf.buf, cbuf.len);
+   strbuf_write_or_die(cbuf, fd);
 
strbuf_release(cbuf);
strbuf_release(buf);
@@ -167,14 +167,14 @@ static void create_note(const unsigned char *object, 
struct msg_arg *msg,
die_errno(_(could not create file '%s'), path);
 
if (msg-given)
-   write_or_die(fd, msg-buf.buf, msg-buf.len);
+   strbuf_write_or_die((msg-buf), fd);
else if (prev  !append_only)
write_note_data(fd, prev);
 
strbuf_addch(buf, '\n');
strbuf_add_commented_lines(buf, note_template, 
strlen(note_template));
strbuf_addch(buf, '\n');
-   write_or_die(fd, buf.buf, buf.len);
+   strbuf_write_or_die(buf, fd);
 
write_commented_object(fd, object);
 
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 85bba35..d590993 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1114,7 +1114,7 @@ static void report(struct command *commands, const char 
*unpack_status)
if (use_sideband)
send_sideband(1, 1, buf.buf, buf.len, use_sideband);
else
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(buf, 1);
strbuf_release(buf);
 }
 
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index f420b74..f26ba21 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -86,7 +86,7 @@ static void print_helper_status(struct ref *ref)
}
strbuf_addch(buf, '\n');
 
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(buf, 1);
}
strbuf_release(buf);
 }
diff --git a/builtin/stripspace.c b/builtin/stripspace.c
index 1259ed7..33b7f85 100644
--- a/builtin/stripspace.c
+++ b/builtin/stripspace.c
@@ -115,7 +115,7 @@ int cmd_stripspace(int argc, const char **argv, const char 
*prefix)
else
comment_lines(buf);
 
-   write_or_die(1, buf.buf, buf.len);
+   strbuf_write_or_die(buf, 1);
strbuf_release(buf);
return 0;
 }
diff --git a/builtin/tag.c b/builtin/tag.c
index 74d3780..53ab280 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -349,7 +349,7 @@ static void create_tag(const unsigned char *object, const 
char *tag,
strbuf_commented_addf(buf, _(tag_template), 
comment_line_char);
else
strbuf_commented_addf(buf, 
_(tag_template_nocleanup), comment_line_char);
-   write_or_die(fd, buf.buf, buf.len);
+   strbuf_write_or_die(buf, fd);
strbuf_release(buf);
}
close(fd);
diff --git a/bundle.c b/bundle.c
index e99065c..c8bddd8 100644
--- a/bundle.c
+++ b/bundle.c
@@ -279,7 +279,7 @@ int create_bundle(struct bundle_header *header, const char 
*path,
while (strbuf_getwholeline(buf, rls_fout, '\n') != EOF) {
unsigned char sha1[20];
if (buf.len  0  buf.buf[0] == '-') {
-   write_or_die(bundle_fd, buf.buf, buf.len);
+   strbuf_write_or_die(buf, bundle_fd);
if (!get_sha1_hex(buf.buf + 1, sha1)) {
struct object *object = 
parse_object_or_die(sha1, buf.buf);
object-flags |= UNINTERESTING;
diff --git a/credential-store.c