Re: `git stash pop` UX Problem
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
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
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
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
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
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 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
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()
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
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
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
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
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()
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()
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
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
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()
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
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/...
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
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
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/....
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
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
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
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
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
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
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()
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
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()
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
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
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
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
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
(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
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/...
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
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
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
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 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()
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
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 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 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
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
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/....
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
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
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
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
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
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
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()
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
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()
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()
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
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
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()
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
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
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
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.
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()
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
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
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
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
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()
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()
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
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
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.
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
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
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
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
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-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
'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()
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()
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