RE: Git Deployment using existing multiple environments
Thank you very much for the detailed reply. There is going to be just one person who'll manage all the moving of the code. On approval he'll move code from one environment to other on our own servers (right now it is being done by manual merging). Development team is not that big right now. They'll be committing all new code to the git repository we have setup up at github using all over test environment code. And the person handling the code at our server will move code from one environment to other by USING Git and not by manual merge. Now lets say we set up a repository at github which has the latest code (all test code)., Now at each of our own servers we already have existing code, that is Test, UAT and Live. For example, first he'll pull code from github to our Test Server and then move branches to UAT and then to Live. Can it work? If it can work then can I please get some some example commands or the procedure to set it up? Time is a bit of problem right now or I would have read book suggested by Johannes. I have searched on the internet but couldn't find any similar case. Regards, Sukhwinder Singh > From: jacob.kel...@gmail.com > Date: Mon, 14 Sep 2015 01:32:39 -0700 > Subject: Re: Git Deployment using existing multiple environments > To: php_programmer_in...@hotmail.com > CC: johannes.schinde...@gmx.de; git@vger.kernel.org > > On Sun, Sep 13, 2015 at 10:55 PM, Sukhwinder Singh > wrote: >> Thank you for the reply. Let's say I do setup three different repositories >> then how can we move work from one repository to the other. For example, >> from Test Environment to UAT. If there are any links that you can provide me >> that I can check, it'll be great. >> >> Regards, >> Sukhwinder Singh >> > > Generally speaking there are two ways of moving work from one > repository to another. The first is the "pull" where you request data > from a remote repository and then merge that data into your own. This > is what you're doing when you perform a clone, a fetch, or a pull. > It's what everyone does all the time when working with a local copy of > a "trusted" remote repository. It can also be done between two > "trusted" remotes, if your workflow is more distributed. (ie: more > than one "official" source). > > The second form of moving work is the "push" where you upload your > work into another repository. This is most commonly used when the > workflow is "centralized". By that I mean there is a single > authoritative repository. Or when you are moving your own work on a > local machine into a remotely accessible machine for others to pull > from. > > As Johannes said above, you really need to determine the work flow and > team style you want before you can really understand the best way to > setup repositories. For example, if you setup using a distributed > chain of command, you can have one person be the "maintainer" of each > given trusted repository. Then, maintainers can pull (or > equivalent-ly, pull-request) between each other. This is generally how > a project would work when using github. One person is the maintainer, > then a developer "forks" the project, makes some changes, then > requests that the maintainer pull these changes. The maintainer has > final say and will perform the final merge in cases of conflict. In > addition, maintainer is the one who says "this is ok to go into this > repository". > > You can also instead opt to use a single centralized repository. Thus, > developers would work on code and get it ready to submit, and then > simply perform a push. If the push requires a merge git will tell the > user to update. There are many tools such as server side hooks in > order to enforce various behaviors. > > This flow generally doesn't use sole maintainers, as each developer > has access to push directly. It may work well for smaller teams or for > dedicated teams who don't change developers often. > > A lot comes down to how your team is structured. Do you have one > person who's job can be to maintain the repository? Do you have > several developers who don't want to be the sole owner? Is your team > willing to function much more distributed? > > In the end, it's generally always a good idea to designate at least > one repository as the "authority" so that everyone knows where to look > for release tags and other such data. > > Myself, I would say that I prefer to use the pull-request model so > that code gets more review, as "push" based models tend not to do > review. (Exception: Gerrit, but this uses "git push" on the command > line to do something very much not like a push) > > Regards, > Jake -- 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] strtoul_ui: actually report error in case of negative input
[ Cc-ing Michael Haggerty who wrote the numparse module ] Max Kirillov writes: > On Mon, Sep 14, 2015 at 08:30:54AM +0200, Matthieu Moy wrote: >>> Fix it by changing the last check to trigger earlier, as soon as it >>> becomes bigger than INT_MAX. >> >> What if the value is actually greater than INT_MAX? The function is >> returning an unsigned long (64 bits on 64bits architectures), and your >> version is restricting it to integers smaller than 2^31, right? > > the return type of the function is "int", so this is not > going to work anyway. Not just the return type (which is the error status), but also the type of the result argument indeed. It's not clear to me whether this is intentional (09f2825 (git-grep: don't use sscanf, 2007-03-12) introduced it, the commit message doesn't help). I first read strtoul_ui as "strtoul with a better UI (user interface)", but maybe the name was meant to say "a fuction that uses strtoul and returns an ui (unsigned int)". I think it would be better to just return a long to avoid needless limitations, but changing the argument to "long" would interfer with in-flight topics. Not worth the trouble. One potential issue with your patch is that you're forbidding the interval [2^31, 2^32[ which was previously allowed, both on 32 and 64 bits. I'm not sure whether we have a use for this in the codebase. This alternative patch is rather ugly to, but I think it is less limiting and does not have the "large negative wrapped to positive" issue: --- a/git-compat-util.h +++ b/git-compat-util.h @@ -814,6 +814,9 @@ static inline int strtoul_ui(char const *s, int base, unsigned int *result) char *p; errno = 0; + /* negative values would be accepted by strtoul */ + if (strchr(s, '-')) + return -1; ul = strtoul(s, &p, base); if (errno || *p || p == s || (unsigned int) ul != ul) return -1; What do you think? > As I mentioned, some negative values are still accepted > as coresponding mod 2**32 positive numbers (-3221225472 as > 1073741824), so there really is room for improvement, but it > cannot be accomplished just by examining strtoul output. On 64 bits architectures, it's not as bad: you need to go really far in the negatives to wrap to positive values. > I saw in the list archives an attempt to abandon the > function in favor of more accurate parser [1], but seems > like it did not make it into the project. > > [1] http://thread.gmane.org/gmane.comp.version-control.git/265635 I went through the thread quickly, my understanding is that there were more work to do, but no objection to merging. Michael, any plan to resurect the topic? -- 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 v2 2/2] git-p4: handle "Translation of file content failed"
On 14/09/15 17:55, larsxschnei...@gmail.com wrote: From: Lars Schneider A P4 repository can get into a state where it contains a file with type UTF-16 that does not contain a valid UTF-16 BOM. If git-p4 Sorry - what's a BOM? I'm assuming it's not a Bill of Materials? Do we know the mechanism by which we end up in this state? attempts to retrieve the file then the process crashes with a "Translation of file content failed" error. Fix this by detecting this error and retrieving the file as binary instead. The result in Git is the same. Known issue: This works only if git-p4 is executed in verbose mode. In normal mode no exceptions are thrown and git-p4 just exits. Does that mean that the error will only be detected in verbose mode? That doesn't seem right! Signed-off-by: Lars Schneider --- git-p4.py | 27 --- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/git-p4.py b/git-p4.py index 073f87b..5ae25a6 100755 --- a/git-p4.py +++ b/git-p4.py @@ -134,13 +134,11 @@ def read_pipe(c, ignore_error=False): sys.stderr.write('Reading pipe: %s\n' % str(c)) expand = isinstance(c,basestring) -p = subprocess.Popen(c, stdout=subprocess.PIPE, shell=expand) -pipe = p.stdout -val = pipe.read() -if p.wait() and not ignore_error: -die('Command failed: %s' % str(c)) - -return val +p = subprocess.Popen(c, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=expand) +(out, err) = p.communicate() +if p.returncode != 0 and not ignore_error: +die('Command failed: %s\nError: %s' % (str(c), err)) +return out def p4_read_pipe(c, ignore_error=False): real_cmd = p4_build_cmd(c) @@ -2186,10 +2184,17 @@ class P4Sync(Command, P4UserMap): # them back too. This is not needed to the cygwin windows version, # just the native "NT" type. # -text = p4_read_pipe(['print', '-q', '-o', '-', "%s@%s" % (file['depotFile'], file['change']) ]) -if p4_version_string().find("/NT") >= 0: -text = text.replace("\r\n", "\n") -contents = [ text ] +try: +text = p4_read_pipe(['print', '-q', '-o', '-', '%s@%s' % (file['depotFile'], file['change'])]) +except Exception as e: Would it be better to specify which kind of Exception you are catching? Looks like you could get OSError, ValueError and CalledProcessError; it's the last of these you want (I think). +if 'Translation of file content failed' in str(e): +type_base = 'binary' +else: +raise e +else: +if p4_version_string().find('/NT') >= 0: +text = text.replace('\r\n', '\n') +contents = [ text ] The indentation on this bit doesn't look right to me. if type_base == "apple": # Apple filetype files will be streamed as a concatenation of Luke -- 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 configure/make does not honor ARFLAGS
Jeffrey Walton writes: >> Oh, indeed. ac179b4d9. Looks good to me. >> >> My follow-up question was going to be: is this something we should be >> setting in config.mak.uname for appropriate versions of Darwin? It >> wasn't clear to me from Eric's description if this is something that >> particular versions need, or just something that people who want to >> build Universal binaries would choose to use. >> > If you have something that needs testing, then please let me know. I'd > be happy to test it for you. In your copy of Git that is recent enough, please run this: $ git fetch git://git.kernel.org/pub/scm/git/git.git pu $ git checkout -b jw/make-arflags-customizable ac179b4d9 This gives you a rather old maintenance track of Git based on v2.0.5 plus a patch that makes $(ARFLAGS) customizable. Presumably you are building a more recent versions of Git yourself. I do not know which branch you are on, but you should be able to merge this brancch to anything newer than v2.0.x maintenance track. E.g. $ git checkout master $ git merge jw/make-arflags-customizable should merge cleanly and would let you say things like: $ make AR=libtool ARFLAGS='-static -o' with any other build customization you usually use on the command line (or in config.mak, if you prefer). What Jeff King was wondering was if those on platform like you have would benefit if they have something like the attached patch on top of the ac179b4d (Makefile: allow $(ARFLAGS) specified from the command line, 2015-09-10) patch. Pieces of information that is needed to determine if that is a good idea are: * What exact condition we should use in the "ifeq" to identify the class of platforms that want this custom AR/ARFLAGS. * Ask if everybody who shares that particular platform would always want "libtool" and "-static -o" as their custom AR/ARFLAGS. If the answer is "no", i.e. on the same platform, more than one compiler toolchain may be available to the users and not everybody may want to use "libtool" and "-static -o" lie you do, then the approach to auto-determine this settings does not help people, and we should not bother with shipping customized config.mak.uname (instead we'd just tell people to do whatever they want with AR and ARFLAGS from the command line). * If it is worth shipping customized config.mak.uname, determine what things, other than AR/ARFLAGS, would help the uses of the class of platforms we identified above in the new "ifeq" section (e.g. perhaps they may want CC=some-other-cc). config.mak.uname | 4 1 file changed, 4 insertions(+) diff --git a/config.mak.uname b/config.mak.uname index 943c439..247dfed 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -46,6 +46,10 @@ ifeq ($(uname_S),GNU/kFreeBSD) DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease LIBC_CONTAINS_LIBINTL = YesPlease endif +ifeq ($(uname_S),"whatever jeffrey uses") + AR = libtool + ARFLAGS = -static -o +endif ifeq ($(uname_S),UnixWare) CC = cc NEEDS_SOCKET = YesPlease -- 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 1/2] git-p4: add test case for "Translation of file content failed" error
On 09/14/2015 06:55 PM, larsxschnei...@gmail.com wrote: From: Lars Schneider A P4 repository can get into a state where it contains a file with type UTF-16 that does not contain a valid UTF-16 BOM. If git-p4 attempts to retrieve the file then the process crashes with a "Translation of file content failed" error. Signed-off-by: Lars Schneider --- t/t9824-git-p4-handle-utf16-without-bom.sh | 47 ++ 1 file changed, 47 insertions(+) create mode 100755 t/t9824-git-p4-handle-utf16-without-bom.sh diff --git a/t/t9824-git-p4-handle-utf16-without-bom.sh b/t/t9824-git-p4-handle-utf16-without-bom.sh new file mode 100755 index 000..fa8043b --- /dev/null +++ b/t/t9824-git-p4-handle-utf16-without-bom.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +test_description='git p4 handle UTF-16 without BOM' + +. ./lib-git-p4.sh + +UTF16="\\x97\\x0\\x97\\x0" + +test_expect_success 'start p4d' ' + start_p4d +' + +test_expect_success 'init depot with UTF-16 encoded file and artificially remove BOM' ' + ( + cd "$cli" && + echo "file1 -text" > .gitattributes && Please no space between '>' and the filename, (this is our coding standard, and the same further down) + perl -e "printf \"$UTF16\"" >file1 && Ehh, do we need perl here ? This will invoke a process-fork, which costs time and cpu load. The following works for me: printf '\227\000\227\000' >file1 -- 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 6/7] t4200: rerere a merge with two identical conflicts
When the context of multiple identical conflicts are different, two seemingly the same conflict resolution cannot be safely applied. In such a case, at least we should be able to record these two resolutions separately in the rerere database, and reuse them when we see the same conflict later. Signed-off-by: Junio C Hamano --- t/t4200-rerere.sh | 74 +++ 1 file changed, 74 insertions(+) diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index 52a8e09..8d52854 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -407,4 +407,78 @@ test_expect_success 'rerere -h' ' test_i18ngrep [Uu]sage help ' +concat_insert () { + last=$1 + shift + cat early && printf "%s\n" "$@" && cat late "$last" +} + +test_expect_failure 'multiple identical conflicts' ' + git reset --hard && + + test_seq 1 6 >early && + >late && + test_seq 11 15 >short && + test_seq 111 120 >long && + concat_insert short >file1 && + concat_insert long >file2 && + git add file1 file2 && + git commit -m base && + git tag base && + git checkout -b six.1 && + concat_insert short 6.1 >file1 && + concat_insert long 6.1 >file2 && + git add file1 file2 && + git commit -m 6.1 && + git checkout -b six.2 HEAD^ && + concat_insert short 6.2 >file1 && + concat_insert long 6.2 >file2 && + git add file1 file2 && + git commit -m 6.2 && + + # At this point, six.1 and six.2 + # - derive from common ancestor that has two files + # 1...6 7 11..15 (file1) and 1...6 7 111..120 (file2) + # - six.1 replaces these 7s with 6.1 + # - six.2 replaces these 7s with 6.2 + + test_must_fail git merge six.1 && + + # Check that rerere knows that file1 and file2 have conflicts + + printf "%s\n" file1 file2 >expect && + git ls-files -u | sed -e "s/^.* //" | sort -u >actual && + test_cmp expect actual && + + git rerere status | sort >actual && + test_cmp expect actual && + + # Resolution is to replace 7 with 6.1 and 6.2 (i.e. take both) + concat_insert short 6.1 6.2 >file1 && + concat_insert long 6.1 6.2 >file2 && + + git rerere remaining >actual && + test_cmp expect actual && + + # We resolved file1 and file2 + git rerere && + >expect && + git rerere remaining >actual && + test_cmp expect actual && + + # Now we should be able to resolve them both + git reset --hard && + test_must_fail git merge six.1 && + git rerere && + + >expect && + git rerere remaining >actual && + test_cmp expect actual && + + concat_insert short 6.1 6.2 >file1.expect && + concat_insert long 6.1 6.2 >file2.expect && + test_cmp file1.expect file1 && + test_cmp file2.expect file2 +' + test_done -- 2.6.0-rc2-164-gdcd5d00 -- 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/7] rerere: scan $GIT_DIR/rr-cache/$ID when instantiating a rerere_id
This will help fixing bootstrap corner-case issues, e.g. having an empty $GIT_DIR/rr-cache/$ID directory would fail to record a preimage, in later changes in this series. Signed-off-by: Junio C Hamano --- rerere.c | 32 +--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/rerere.c b/rerere.c index a5d8a06..fbdade8 100644 --- a/rerere.c +++ b/rerere.c @@ -26,8 +26,11 @@ static char *merge_rr_path; static int rerere_dir_nr; static int rerere_dir_alloc; +#define RR_HAS_POSTIMAGE 1 +#define RR_HAS_PREIMAGE 2 static struct rerere_dir { unsigned char sha1[20]; + unsigned char status; } **rerere_dir; static void free_rerere_dirs(void) @@ -58,6 +61,27 @@ const char *rerere_path(const struct rerere_id *id, const char *file) return git_path("rr-cache/%s/%s", rerere_id_hex(id), file); } +static int is_rr_file(const char *name, const char *filename) +{ + return !strcmp(name, filename); +} + +static void scan_rerere_dir(struct rerere_dir *rr_dir) +{ + struct dirent *de; + DIR *dir = opendir(git_path("rr-cache/%s", sha1_to_hex(rr_dir->sha1))); + + if (!dir) + return; + while ((de = readdir(dir)) != NULL) { + if (is_rr_file(de->d_name, "postimage")) + rr_dir->status |= RR_HAS_POSTIMAGE; + else if (is_rr_file(de->d_name, "preimage")) + rr_dir->status |= RR_HAS_PREIMAGE; + } + closedir(dir); +} + static const unsigned char *rerere_dir_sha1(size_t i, void *table) { struct rerere_dir **rr_dir = table; @@ -76,6 +100,7 @@ static struct rerere_dir *find_rerere_dir(const char *hex) if (pos < 0) { rr_dir = xmalloc(sizeof(*rr_dir)); hashcpy(rr_dir->sha1, sha1); + rr_dir->status = 0; pos = -1 - pos; /* Make sure the array is big enough ... */ @@ -85,15 +110,14 @@ static struct rerere_dir *find_rerere_dir(const char *hex) memmove(rerere_dir + pos + 1, rerere_dir + pos, (rerere_dir_nr - pos - 1) * sizeof(*rerere_dir)); rerere_dir[pos] = rr_dir; + scan_rerere_dir(rr_dir); } return rerere_dir[pos]; } static int has_rerere_resolution(const struct rerere_id *id) { - struct stat st; - - return !stat(rerere_path(id, "postimage"), &st); + return (id->collection->status & RR_HAS_POSTIMAGE); } static struct rerere_id *new_rerere_id_hex(char *hex) @@ -737,6 +761,7 @@ static void do_rerere_one_path(struct string_list_item *rr_item, } else if (!handle_file(path, NULL, NULL)) { /* The user has resolved it. */ copy_file(rerere_path(id, "postimage"), path, 0666); + id->collection->status |= RR_HAS_POSTIMAGE; fprintf(stderr, "Recorded resolution for '%s'.\n", path); } else { return; @@ -797,6 +822,7 @@ static int do_plain_rerere(struct string_list *rr, int fd) * normalized contents to the "preimage" file. */ handle_file(path, NULL, rerere_path(id, "preimage")); + id->collection->status |= RR_HAS_PREIMAGE; fprintf(stderr, "Recorded preimage for '%s'\n", path); } -- 2.6.0-rc2-164-gdcd5d00 -- 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/7] rerere: handle leftover rr-cache/$ID directory and postimage files
If by some accident there is only $GIT_DIR/rr-cache/$ID directory existed, we wouldn't have recorded a preimage for a conflict that is newly encountered, which would mean after a manual resolution, we wouldn't have recorded it by storing the postimage, because the logic used to be "if there is no rr-cache/$ID directory, then we are the first so record the preimage". Instead, record preimage if we do not have one. In addition, if there is only $GIT_DIR/rr-cache/$ID/postimage without corresponding preimage, we would have tried to call into merge() and punted. These would have been a situation frustratingly hard to recover from. Signed-off-by: Junio C Hamano --- rerere.c | 42 +- t/t4200-rerere.sh | 18 +- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/rerere.c b/rerere.c index fbdade8..a1e2963 100644 --- a/rerere.c +++ b/rerere.c @@ -117,7 +117,9 @@ static struct rerere_dir *find_rerere_dir(const char *hex) static int has_rerere_resolution(const struct rerere_id *id) { - return (id->collection->status & RR_HAS_POSTIMAGE); + const int both = RR_HAS_POSTIMAGE|RR_HAS_PREIMAGE; + + return ((id->collection->status & both) == both); } static struct rerere_id *new_rerere_id_hex(char *hex) @@ -806,24 +808,30 @@ static int do_plain_rerere(struct string_list *rr, int fd) string_list_insert(rr, path)->util = id; /* -* If the directory does not exist, create -* it. mkdir_in_gitdir() will fail with -* EEXIST if there already is one. -* -* NEEDSWORK: make sure "gc" does not remove -* preimage without removing the directory. +* Ensure that the directory exists. +* mkdir_in_gitdir() will fail with EEXIST if there +* already is one. */ - if (mkdir_in_gitdir(rerere_path(id, NULL))) - continue; + if (mkdir_in_gitdir(rerere_path(id, NULL)) && + errno != EEXIST) + continue; /* NEEDSWORK: perhaps we should die? */ - /* -* We are the first to encounter this -* conflict. Ask handle_file() to write the -* normalized contents to the "preimage" file. -*/ - handle_file(path, NULL, rerere_path(id, "preimage")); - id->collection->status |= RR_HAS_PREIMAGE; - fprintf(stderr, "Recorded preimage for '%s'\n", path); + if (id->collection->status & RR_HAS_PREIMAGE) { + ; + } else { + /* +* We are the first to encounter this +* conflict. Ask handle_file() to write the +* normalized contents to the "preimage" file. +* +* NEEDSWORK: what should happen if we had a +* leftover postimage that is totally +* unrelated? Perhaps we should unlink it? +*/ + handle_file(path, NULL, rerere_path(id, "preimage")); + id->collection->status |= RR_HAS_PREIMAGE; + fprintf(stderr, "Recorded preimage for '%s'\n", path); + } } for (i = 0; i < rr->nr; i++) diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index ed9c91e..52a8e09 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -184,12 +184,28 @@ test_expect_success 'rerere updates postimage timestamp' ' ' test_expect_success 'rerere clear' ' - rm $rr/postimage && + cp $rr/preimage .git/pre-saved && + mv $rr/postimage .git/post-saved && echo "$sha1 a1" | perl -pe "y/\012/\000/" >.git/MERGE_RR && git rerere clear && ! test -d $rr ' +test_expect_success 'leftover directory' ' + git reset --hard && + mkdir -p $rr && + test_must_fail git merge first && + test -f $rr/preimage +' + +test_expect_success 'missing preimage' ' + git reset --hard && + mkdir -p $rr && + cp .git/post-saved $rr/postimage && + test_must_fail git merge first && + test -f $rr/preimage +' + test_expect_success 'set up for garbage collection tests' ' mkdir -p $rr && echo Hello >$rr/preimage && -- 2.6.0-rc2-164-gdcd5d00 -- 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 7/7] rerere: do use multiple variants
This enables the multiple-variant support for real. Multiple conflicts of the same shape can have differences in contexts where they appear, interfering the replaying of recorded resolution of one conflict to another, and in such a case, their resolutions are recorded as different variants under the same conflict ID. We still need to adjust garbage collection codepaths for this change, but the basic "replay" functionality is functional with this change. Signed-off-by: Junio C Hamano --- rerere.c | 94 +-- t/t4200-rerere.sh | 2 +- 2 files changed, 57 insertions(+), 39 deletions(-) diff --git a/rerere.c b/rerere.c index f674461..cefc865 100644 --- a/rerere.c +++ b/rerere.c @@ -74,7 +74,9 @@ static void assign_variant(struct rerere_id *id) variant = id->variant; if (variant < 0) { - variant = 0; /* for now */ + for (variant = 0; variant < rr_dir->status_nr; variant++) + if (!rr_dir->status[variant]) + break; } fit_variant(rr_dir, variant); id->variant = variant; @@ -177,15 +179,6 @@ static int has_rerere_resolution(const struct rerere_id *id) return ((id->collection->status[variant] & both) == both); } -static int has_rerere_preimage(const struct rerere_id *id) -{ - int variant = id->variant; - - if (variant < 0) - return 0; - return (id->collection->status[variant] & RR_HAS_PREIMAGE); -} - static struct rerere_id *new_rerere_id_hex(char *hex) { struct rerere_id *id = xmalloc(sizeof(*id)); @@ -818,6 +811,13 @@ static void update_paths(struct string_list *update) rollback_lock_file(&index_lock); } +static void remove_variant(struct rerere_id *id) +{ + unlink_or_warn(rerere_path(id, "postimage")); + unlink_or_warn(rerere_path(id, "preimage")); + id->collection->status[id->variant] = 0; +} + /* * The path indicated by rr_item may still have conflict for which we * have a recorded resolution, in which case replay it and optionally @@ -830,32 +830,42 @@ static void do_rerere_one_path(struct string_list_item *rr_item, { const char *path = rr_item->string; struct rerere_id *id = rr_item->util; + struct rerere_dir *rr_dir = id->collection; int variant; - if (id->variant < 0) - assign_variant(id); variant = id->variant; - if (!has_rerere_preimage(id)) { + /* Has the user resolved it already? */ + if (variant >= 0) { + if (!handle_file(path, NULL, NULL)) { + copy_file(rerere_path(id, "postimage"), path, 0666); + id->collection->status[variant] |= RR_HAS_POSTIMAGE; + fprintf(stderr, "Recorded resolution for '%s'.\n", path); + free_rerere_id(rr_item); + rr_item->util = NULL; + return; + } /* -* We are the first to encounter this conflict. Ask -* handle_file() to write the normalized contents to -* the "preimage" file. +* There may be other variants that can cleanly +* replay. Try them and update the variant number for +* this one. */ - handle_file(path, NULL, rerere_path(id, "preimage")); - if (id->collection->status[variant] & RR_HAS_POSTIMAGE) { - const char *path = rerere_path(id, "postimage"); - if (unlink(path)) - die_errno("cannot unlink stray '%s'", path); - id->collection->status[variant] &= ~RR_HAS_PREIMAGE; - } - id->collection->status[variant] |= RR_HAS_PREIMAGE; - fprintf(stderr, "Recorded preimage for '%s'\n", path); - return; - } else if (has_rerere_resolution(id)) { - /* Is there a recorded resolution we could attempt to apply? */ - if (merge(id, path)) - return; /* failed to replay */ + } + + /* Does any existing resolution apply cleanly? */ + for (variant = 0; variant < rr_dir->status_nr; variant++) { + const int both = RR_HAS_PREIMAGE | RR_HAS_POSTIMAGE; + struct rerere_id vid = *id; + + if ((rr_dir->status[variant] & both) != both) + continue; + + vid.variant = variant; + if (merge(&vid, path)) + continue; /* failed to replay */ + + if (0 <= id->variant && id->variant != variant) + remove_variant(id); if (rerere_autoupdate) string_list_insert(update, path); @@ -863,16 +873,24 @@ static void do_rerere_one_path(struct
[PATCH 5/7] rerere: allow multiple variants to exist
The shape of the conflict in a path determines the conflict ID. The preimage and postimage pair that was recorded for the conflict ID previously may or may not replay well for the conflict we just saw. Currently, we punt when the previous resolution does not cleanly replay, but ideally we should then be able to record the currently conflicted path by assigning a new 'variant', and then record the resolution the user is going to make. Introduce a mechanism to have more than one variant for a given conflict ID; we do not actually assign any variant other than 0th variant yet at this step. Signed-off-by: Junio C Hamano --- rerere.c | 127 --- rerere.h | 1 + 2 files changed, 106 insertions(+), 22 deletions(-) diff --git a/rerere.c b/rerere.c index c0482b8..f674461 100644 --- a/rerere.c +++ b/rerere.c @@ -30,14 +30,17 @@ static int rerere_dir_alloc; #define RR_HAS_PREIMAGE 2 static struct rerere_dir { unsigned char sha1[20]; - unsigned char status; + int status_alloc, status_nr; + unsigned char *status; } **rerere_dir; static void free_rerere_dirs(void) { int i; - for (i = 0; i < rerere_dir_nr; i++) + for (i = 0; i < rerere_dir_nr; i++) { + free(rerere_dir[i]->status); free(rerere_dir[i]); + } free(rerere_dir); rerere_dir_nr = rerere_dir_alloc = 0; rerere_dir = NULL; @@ -53,17 +56,59 @@ static const char *rerere_id_hex(const struct rerere_id *id) return sha1_to_hex(id->collection->sha1); } +static void fit_variant(struct rerere_dir *rr_dir, int variant) +{ + variant++; + ALLOC_GROW(rr_dir->status, variant, rr_dir->status_alloc); + if (rr_dir->status_nr < variant) { + memset(rr_dir->status + rr_dir->status_nr, + '\0', variant - rr_dir->status_nr); + rr_dir->status_nr = variant; + } +} + +static void assign_variant(struct rerere_id *id) +{ + int variant; + struct rerere_dir *rr_dir = id->collection; + + variant = id->variant; + if (variant < 0) { + variant = 0; /* for now */ + } + fit_variant(rr_dir, variant); + id->variant = variant; +} + const char *rerere_path(const struct rerere_id *id, const char *file) { if (!file) return git_path("rr-cache/%s", rerere_id_hex(id)); - return git_path("rr-cache/%s/%s", rerere_id_hex(id), file); + if (id->variant <= 0) + return git_path("rr-cache/%s/%s", rerere_id_hex(id), file); + + return git_path("rr-cache/%s/%s.%d", + rerere_id_hex(id), file, id->variant); } -static int is_rr_file(const char *name, const char *filename) +static int is_rr_file(const char *name, const char *filename, int *variant) { - return !strcmp(name, filename); + const char *suffix; + char *ep; + + if (!strcmp(name, filename)) { + *variant = 0; + return 1; + } + if (!skip_prefix(name, filename, &suffix) || *suffix != '.') + return 0; + + errno = 0; + *variant = strtol(suffix + 1, &ep, 10); + if (errno || *ep) + return 0; + return 1; } static void scan_rerere_dir(struct rerere_dir *rr_dir) @@ -74,10 +119,15 @@ static void scan_rerere_dir(struct rerere_dir *rr_dir) if (!dir) return; while ((de = readdir(dir)) != NULL) { - if (is_rr_file(de->d_name, "postimage")) - rr_dir->status |= RR_HAS_POSTIMAGE; - else if (is_rr_file(de->d_name, "preimage")) - rr_dir->status |= RR_HAS_PREIMAGE; + int variant; + + if (is_rr_file(de->d_name, "postimage", &variant)) { + fit_variant(rr_dir, variant); + rr_dir->status[variant] |= RR_HAS_POSTIMAGE; + } else if (is_rr_file(de->d_name, "preimage", &variant)) { + fit_variant(rr_dir, variant); + rr_dir->status[variant] |= RR_HAS_PREIMAGE; + } } closedir(dir); } @@ -100,7 +150,9 @@ static struct rerere_dir *find_rerere_dir(const char *hex) if (pos < 0) { rr_dir = xmalloc(sizeof(*rr_dir)); hashcpy(rr_dir->sha1, sha1); - rr_dir->status = 0; + rr_dir->status = NULL; + rr_dir->status_nr = 0; + rr_dir->status_alloc = 0; pos = -1 - pos; /* Make sure the array is big enough ... */ @@ -118,19 +170,27 @@ static struct rerere_dir *find_rerere_dir(const char *hex) static int has_rerere_resolution(const struct rerere_id *id) { const int both = RR_HAS_POSTIMAGE|RR_HAS_PREIMAGE; + int variant = id->variant; - return ((id->collection->status & both) == both); +
[PATCH 4/7] rerere: delay the recording of preimage
We record the preimage only when there is no directory to record the conflict we encountered, i.e. when $GIT_DIR/rr-cache/$ID does not exist. As the plan is to allow multiple pairs as variants for the same conflict ID eventually, this logic needs to go. As the first step in that direction, stop the "did we create the directory? Then we record the preimage" logic. Instead, we record if a preimage does not exist when we saw a conflict in a path. Also make sure that we create a new preimage under $ID with existing stale postimage, which most likely is totally unrelated to the resolution of this new conflict. In later patches, we will further update this logic to be "do we have pair that cleanly resolve the current conflicts? If not, record a new preimage as a new variant", but that does not happen at this stage yet. Signed-off-by: Junio C Hamano --- rerere.c | 52 +--- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/rerere.c b/rerere.c index a1e2963..c0482b8 100644 --- a/rerere.c +++ b/rerere.c @@ -122,6 +122,11 @@ static int has_rerere_resolution(const struct rerere_id *id) return ((id->collection->status & both) == both); } +static int has_rerere_preimage(const struct rerere_id *id) +{ + return (id->collection->status & RR_HAS_PREIMAGE); +} + static struct rerere_id *new_rerere_id_hex(char *hex) { struct rerere_id *id = xmalloc(sizeof(*id)); @@ -749,8 +754,24 @@ static void do_rerere_one_path(struct string_list_item *rr_item, const char *path = rr_item->string; const struct rerere_id *id = rr_item->util; - /* Is there a recorded resolution we could attempt to apply? */ - if (has_rerere_resolution(id)) { + if (!has_rerere_preimage(id)) { + /* +* We are the first to encounter this conflict. Ask +* handle_file() to write the normalized contents to +* the "preimage" file. +*/ + handle_file(path, NULL, rerere_path(id, "preimage")); + if (id->collection->status & RR_HAS_POSTIMAGE) { + const char *path = rerere_path(id, "postimage"); + if (unlink(path)) + die_errno("cannot unlink stray '%s'", path); + id->collection->status &= ~RR_HAS_PREIMAGE; + } + id->collection->status |= RR_HAS_PREIMAGE; + fprintf(stderr, "Recorded preimage for '%s'\n", path); + return; + } else if (has_rerere_resolution(id)) { + /* Is there a recorded resolution we could attempt to apply? */ if (merge(id, path)) return; /* failed to replay */ @@ -807,31 +828,8 @@ static int do_plain_rerere(struct string_list *rr, int fd) id = new_rerere_id(sha1); string_list_insert(rr, path)->util = id; - /* -* Ensure that the directory exists. -* mkdir_in_gitdir() will fail with EEXIST if there -* already is one. -*/ - if (mkdir_in_gitdir(rerere_path(id, NULL)) && - errno != EEXIST) - continue; /* NEEDSWORK: perhaps we should die? */ - - if (id->collection->status & RR_HAS_PREIMAGE) { - ; - } else { - /* -* We are the first to encounter this -* conflict. Ask handle_file() to write the -* normalized contents to the "preimage" file. -* -* NEEDSWORK: what should happen if we had a -* leftover postimage that is totally -* unrelated? Perhaps we should unlink it? -*/ - handle_file(path, NULL, rerere_path(id, "preimage")); - id->collection->status |= RR_HAS_PREIMAGE; - fprintf(stderr, "Recorded preimage for '%s'\n", path); - } + /* Ensure that the directory exists. */ + mkdir_in_gitdir(rerere_path(id, NULL)); } for (i = 0; i < rr->nr; i++) -- 2.6.0-rc2-164-gdcd5d00 -- 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/7] rerere: split conflict ID further
The plan is to keep assigning the backward compatible conflict ID based on the hash of the (normalized) text of conflicts, keep using that conflict ID as the directory name under $GIT_DIR/rr-cache/, but allow each conflicted path to use a separate "variant" to record resolutions, i.e. having more than one pairs under $GIT_DIR/rr-cache/$ID/ directory. As the first step in that direction, separate the shared "conflict ID" out of the rerere_id structure. The plan is to keep information per $ID in rerere_dir, that can be shared among rerere_id that is per conflicted path. When we are done with rerere(), which can be directly called from other programs like "git apply", "git commit" and "git merge", the shared rerere_dir structures can be freed entirely, so they are not reference-counted and they are not freed when we release rerere_id's that reference them. Signed-off-by: Junio C Hamano --- rerere.c | 61 - rerere.h | 3 ++- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/rerere.c b/rerere.c index 9bef24f..a5d8a06 100644 --- a/rerere.c +++ b/rerere.c @@ -8,6 +8,7 @@ #include "ll-merge.h" #include "attr.h" #include "pathspec.h" +#include "sha1-lookup.h" #define RESOLVED 0 #define PUNTED 1 @@ -22,6 +23,23 @@ static int rerere_autoupdate; static char *merge_rr_path; +static int rerere_dir_nr; +static int rerere_dir_alloc; + +static struct rerere_dir { + unsigned char sha1[20]; +} **rerere_dir; + +static void free_rerere_dirs(void) +{ + int i; + for (i = 0; i < rerere_dir_nr; i++) + free(rerere_dir[i]); + free(rerere_dir); + rerere_dir_nr = rerere_dir_alloc = 0; + rerere_dir = NULL; +} + static void free_rerere_id(struct string_list_item *item) { free(item->util); @@ -29,7 +47,7 @@ static void free_rerere_id(struct string_list_item *item) static const char *rerere_id_hex(const struct rerere_id *id) { - return id->hex; + return sha1_to_hex(id->collection->sha1); } const char *rerere_path(const struct rerere_id *id, const char *file) @@ -40,6 +58,37 @@ const char *rerere_path(const struct rerere_id *id, const char *file) return git_path("rr-cache/%s/%s", rerere_id_hex(id), file); } +static const unsigned char *rerere_dir_sha1(size_t i, void *table) +{ + struct rerere_dir **rr_dir = table; + return rr_dir[i]->sha1; +} + +static struct rerere_dir *find_rerere_dir(const char *hex) +{ + unsigned char sha1[20]; + struct rerere_dir *rr_dir; + int pos; + + if (get_sha1_hex(hex, sha1)) + return NULL; /* BUG */ + pos = sha1_pos(sha1, rerere_dir, rerere_dir_nr, rerere_dir_sha1); + if (pos < 0) { + rr_dir = xmalloc(sizeof(*rr_dir)); + hashcpy(rr_dir->sha1, sha1); + pos = -1 - pos; + + /* Make sure the array is big enough ... */ + ALLOC_GROW(rerere_dir, rerere_dir_nr + 1, rerere_dir_alloc); + /* ... and add it in. */ + rerere_dir_nr++; + memmove(rerere_dir + pos + 1, rerere_dir + pos, + (rerere_dir_nr - pos - 1) * sizeof(*rerere_dir)); + rerere_dir[pos] = rr_dir; + } + return rerere_dir[pos]; +} + static int has_rerere_resolution(const struct rerere_id *id) { struct stat st; @@ -50,7 +99,7 @@ static int has_rerere_resolution(const struct rerere_id *id) static struct rerere_id *new_rerere_id_hex(char *hex) { struct rerere_id *id = xmalloc(sizeof(*id)); - strcpy(id->hex, hex); + id->collection = find_rerere_dir(hex); return id; } @@ -810,12 +859,14 @@ int setup_rerere(struct string_list *merge_rr, int flags) int rerere(int flags) { struct string_list merge_rr = STRING_LIST_INIT_DUP; - int fd; + int fd, status; fd = setup_rerere(&merge_rr, flags); if (fd < 0) return 0; - return do_plain_rerere(&merge_rr, fd); + status = do_plain_rerere(&merge_rr, fd); + free_rerere_dirs(); + return status; } static int rerere_forget_one_path(const char *path, struct string_list *rr) @@ -900,7 +951,7 @@ int rerere_forget(struct pathspec *pathspec) static struct rerere_id *dirname_to_id(const char *name) { static struct rerere_id id; - strcpy(id.hex, name); + id.collection = find_rerere_dir(name); return &id; } diff --git a/rerere.h b/rerere.h index ce545d0..faf5a23 100644 --- a/rerere.h +++ b/rerere.h @@ -15,8 +15,9 @@ struct pathspec; */ extern void *RERERE_RESOLVED; +struct rerere_dir; struct rerere_id { - char hex[41]; + struct rerere_dir *collection; }; extern int setup_rerere(struct string_list *, int); -- 2.6.0-rc2-164-gdcd5d00 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo
[PATCH 0/7] saving and replaying multiple variants with rerere
This is a continuation of jc/rerere topic that is now in 'next'. The old topic is purely about refactoring and code cleaning and this series builds on top of it. We record a previously seen conflict and its resolution in a subdirectory of $GIT_DIR/rr-cache, and the name of the subdirectory is computed by hashing the "shape" of the conflicted hunk. When a similar-looking conflict is encountered later in the working tree, "git rerere" tries to replay the recorded resolution by running a three-way merge to apply the change to go from the previous conflict to the previous resolution to the current conflicted state. Depending on what appears in the context around the conflicted hunk, however, this three-way merge itself can conflict and fail to apply to a seemingly identical conflict. You _could_ argue that you could merge with reduced context lines to work around the problem, but that is a risky proposition. As a safer approach, these patches allow us to keep more than one pairs of (i.e. conflicted state and its resolution) in the same "shape". If two paths have identical looking conflict and one's resolution does not cleanly replay to the other's conflicted state, we now save the resolutions of these two paths as different "variants" so that they can be applied when we see these conflicts again. I think the basic "record and replay" part is done with this round, but I haven't really reviewed the part that deals with garbage collection of old rerere database entries, which probably needs more work (and could use help, hints hints...). Junio C Hamano (7): rerere: split conflict ID further rerere: scan $GIT_DIR/rr-cache/$ID when instantiating a rerere_id rerere: handle leftover rr-cache/$ID directory and postimage files rerere: delay the recording of preimage rerere: allow multiple variants to exist t4200: rerere a merge with two identical conflicts rerere: do use multiple variants rerere.c | 270 +- rerere.h | 4 +- t/t4200-rerere.sh | 92 ++- 3 files changed, 321 insertions(+), 45 deletions(-) -- 2.6.0-rc2-164-gdcd5d00 -- 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 configure/make does not honor ARFLAGS
On Mon, Sep 14, 2015 at 12:59 AM, Jeff King wrote: > On Sun, Sep 13, 2015 at 09:57:08PM -0700, Junio C Hamano wrote: > >> On Sun, Sep 13, 2015 at 9:30 PM, Jeff King wrote: >> > >> > Ah, OK. Today I learned something. :) >> > >> > Jeffrey, can you produce a tested patch which works for you? >> >> If I am not mistaken, I think I already have one on 'pu' (I think I did that >> as an afternoon-tea time hack or something). > > Oh, indeed. ac179b4d9. Looks good to me. > > My follow-up question was going to be: is this something we should be > setting in config.mak.uname for appropriate versions of Darwin? It > wasn't clear to me from Eric's description if this is something that > particular versions need, or just something that people who want to > build Universal binaries would choose to use. > If you have something that needs testing, then please let me know. I'd be happy to test it for you. My OS X test environment includes OS X 10.5 PoweMac (PowerPC), 10.8 Intel x64 (ancient C++ stdlib that claims to be C++11), and 10.9 Intel x64. If desired, I can give you SSH access to a couple of the machines. OpenSSL and Cryptlib uses them on occasion for testing, too. Jeff -- 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
[L10N] Kickoff of translation for Git 2.6.0 round 2
Hi, Git v2.6.0-rc2 had been released, and introduced three i18n improvements. Please update your translations based on this commit: l10n: git.pot: v2.6.0 round 2 (3 improvements) Introduce three i18n improvements from the following commits: * tag, update-ref: improve description of option "create-reflog" * pull: don't mark values for option "rebase" for translation * show-ref: place angle brackets around variables in usage string Signed-off-by: Jiang Xin You can get it from the usual place: https://github.com/git-l10n/git-po/ As how to update your XX.po and help to translate Git, please see "Updating a XX.po file" and other sections in “po/README" file. -- Jiang Xin -- 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
What's cooking in git.git (Sep 2015, #03; Mon, 14)
Here are the topics that have been cooking. Commits prefixed with '-' are only in 'pu' (proposed updates) while commits prefixed with '+' are in 'next'. The tip of 'master' is slightly past 2.6-rc2; hopefully l10n team can work on this without updates before the end of the cycle. You can find the changes described here in the integration branches of the repositories listed at http://git-blame.blogspot.com/p/git-public-repositories.html -- [Graduated to "master"] * ah/show-ref-usage-string (2015-08-31) 1 commit (merged to 'next' on 2015-09-08 at dc512c8) + show-ref: place angle brackets around variables in usage string Both "git show-ref -h" and "git show-ref --help" illustrated that the "--exclude-existing" option makes the command read list of refs from its standard input. Change only the "show-ref -h" output to have a pair of "<>" around the placeholder that designate an input file, i.e. "git show-ref --exclude-existing < ". * gb/apply-comment-typofix (2015-09-09) 1 commit (merged to 'next' on 2015-09-09 at 29fb0ff) + apply: comment grammar fix * jk/pack-protocol-doc (2015-09-03) 1 commit (merged to 'next' on 2015-09-08 at 98d861d) + pack-protocol: clarify LF-handling in PKT-LINE() Streamline documentation of the pkt-line protocol. * js/maint-am-skip-performance-regression (2015-09-09) 1 commit (merged to 'next' on 2015-09-14 at b669ea1) + am --skip/--abort: merge HEAD/ORIG_HEAD tree into index Later versions of scripted "git am" has a performance regression in "git am --skip" codepath, which no longer exists in the built-in version on the 'master' front. Fix the regression in the last scripted version that appear in 2.5.x maintenance track and older. Will merge to 'maint' and older. * mp/t7060-diff-index-test (2015-09-02) 1 commit (merged to 'next' on 2015-09-08 at 80ff284) + t7060: actually test "git diff-index --cached -M" Fix an old test that was doing the same thing as another one. * rt/help-strings-fix (2015-09-11) 2 commits (merged to 'next' on 2015-09-14 at 875908c) + tag, update-ref: improve description of option "create-reflog" + pull: don't mark values for option "rebase" for translation * sg/help-group (2015-09-10) 1 commit (merged to 'next' on 2015-09-14 at cef17e2) + Makefile: use SHELL_PATH when running generate-cmdlist.sh Last minute regression fix. -- [New Topics] * ld/p4-detached-head (2015-09-09) 2 commits - git-p4: work with a detached head - git-p4: add failing test for submit from detached head Will be rerolled. ($gmane/277574) * as/config-doc-markup-fix (2015-09-12) 1 commit (merged to 'next' on 2015-09-14 at faa4134) + Documentation/config: fix formatting for branch.*.rebase and pull.rebase Will merge to 'master'. * et/win32-poll-timeout (2015-09-14) 1 commit (merged to 'next' on 2015-09-14 at 308dff4) + poll: honor the timeout on Win32 Will merge to 'master'. * jk/graph-format-padding (2015-09-14) 1 commit - pretty: pass graph width to pretty formatting for use in '%>|(N)' Redefine the way '%>|(N)' padding and the "--graph" option interacts. It has been that the available columns to display the log message was measured from the edge of the area the graph ended, but with this it becomes the beginning of the entire output. I have a suspicion that 50% of the users would appreciate this change, and the remainder see this break their expectation. If that is the case, we might need to introduce a similar but different alignment operator so that this new behaviour is available to those who want to use it, without negatively affecting existing uses. * jk/make-findstring-makeflags-fix (2015-09-10) 1 commit - Makefile: fix MAKEFLAGS tests with multiple flags Customization to change the behaviour with "make -w" and "make -s" in our Makefile was broken when they were used together. Will merge to 'next'. * jk/rebase-no-autostash (2015-09-10) 2 commits - Documentation/git-rebase: fix --no-autostash formatting - rebase: support --no-autostash There was no way to defeat a configured rebase.autostash variable from the command line, as "git rebase --no-autostash" was missing. Will merge to 'next'. * jw/make-arflags-customizable (2015-09-10) 1 commit - Makefile: allow $(ARFLAGS) specified from the command line The Makefile always runs the library archiver with hardcoded "crs" options, which was inconvenient for exotic platforms on which people wants to use programs with totally different set of command line options. Will merge to 'next'. * nd/ignore-then-not-ignore (2015-09-14) 2 commits - dir.c: don't exclude whole dir prematurely if neg pattern may match - dir.c: make last_exclude_matching_from_list() run til the end Allow a later "!/abc/def" to override an earlier "/abc" that appears in the same .gitignore file to make it easier to express "everything in /abc direc
[ANNOUNCE] Git v2.6.0-rc2
A release candidate Git v2.6.0-rc2 is now available for testing at the usual places. It is comprised of 439 non-merge commits since v2.5.0, contributed by 59 people, 14 of which are new faces. The tarballs are found at: https://www.kernel.org/pub/software/scm/git/testing/ The following public repositories all have a copy of the 'v2.6.0-rc2' tag and the 'master' branch that the tag points at: url = https://kernel.googlesource.com/pub/scm/git/git url = git://repo.or.cz/alt-git.git url = git://git.sourceforge.jp/gitroot/git-core/git.git url = git://git-core.git.sourceforge.net/gitroot/git-core/git-core url = https://github.com/gitster/git New contributors whose contributions weren't in v2.5.0 are as follows. Welcome to the Git development community! Antoine Delaite, Brett Randall, Brian Degenhardt, Erik Elfström, Galan Rémi, Guillaume Pagès, Ismael Luceno, Jan Viktorin, Jose F. Morales, Lars Schneider, Matthieu Prat, Michael Rappazzo, Simon A. Eugster, and Zoë Blade. Returning contributors who helped this release are as follows. Thanks for your continued support. Alexander Shopov, Alex Henrie, Andreas Schwab, Beat Bolli, brian m. carlson, Charles Bailey, Christian Couder, Clemens Buchacher, Dave Borowitz, David Aguilar, David Turner, Elia Pinto, Eric Sunshine, Giuseppe Bilotta, Heiko Voigt, Ilya Bobyr, Jacob Keller, Jeff King, Jiang Xin, Jim Hill, Johannes Schindelin, Johannes Sixt, Junio C Hamano, Karsten Blees, Karthik Nayak, Kevin Daudt, Marc Branchaud, Matthieu Moy, Michael Haggerty, Michael J Gruber, Mike Hommey, Nguyễn Thái Ngọc Duy, Patrick Steinhardt, Paul Mackerras, Paul Tan, Peter Krefting, Philip Oakley, Ralf Thielow, Remi Lespinet, René Scharfe, Stefan Beller, Sven Strickroth, SZEDER Gábor, Thomas Ackermann, and Thomas Braun. Git 2.6 Release Notes (draft) = Updates since v2.5 -- UI, Workflows & Features * An asterisk as a substring (as opposed to the entirety) of a path component for both side of a refspec, e.g. "refs/heads/o*:refs/remotes/heads/i*", is now allowed. * New userdiff pattern definition for fountain screenwriting markup format has been added. * "git log" and friends learned a new "--date=format:..." option to format timestamps using system's strftime(3). * "git fast-import" learned to respond to the get-mark command via its cat-blob-fd interface. * "git rebase -i" learned "drop commit-object-name subject" command as another way to skip replaying of a commit. * A new configuration variable can enable "--follow" automatically when "git log" is run with one pathspec argument. * "git status" learned to show a more detailed information regarding the "rebase -i" session in progress. * "git cat-file" learned "--batch-all-objects" option to enumerate all available objects in the repository more quickly than "rev-list --all --objects" (the output includes unreachable objects, though). * "git fsck" learned to ignore errors on a set of known-to-be-bad objects, and also allows the warning levels of various kinds of non-critical breakages to be tweaked. * "git rebase -i"'s list of todo is made configurable. * "git send-email" now performs alias-expansion on names that are given via --cccmd, etc. * An environment variable GIT_REPLACE_REF_BASE tells Git to look into refs hierarchy other than refs/replace/ for the object replacement data. * Allow untracked cache (experimental) to be used when sparse checkout (experimental) is also in use. * "git pull --rebase" has been taught to pay attention to rebase.autostash configuration. * The command-line completion script (in contrib/) has been updated. * A negative !ref entry in multi-value transfer.hideRefs configuration can be used to say "don't hide this one". * After "git am" without "-3" stops, running "git am -3" pays attention to "-3" only for the patch that caused the original invocation to stop. * When linked worktree is used, simultaneous "notes merge" instances for the same ref in refs/notes/* are prevented from stomping on each other. * "git send-email" learned a new option --smtp-auth to limit the SMTP AUTH mechanisms to be used to a subset of what the system library supports. * A new configuration variable http.sslVersion can be used to specify what specific version of SSL/TLS to use to make a connection. * "git notes merge" can be told with "--strategy=" option how to automatically handle conflicts; this can now be configured by setting notes.mergeStrategy configuration variable. * "git log --cc" did not show any patch, even though most of the time the user meant "git log --cc -p -m" to see patch output for commits with a single parent, and combined diff for merge commits. The command is taught to DWIM "--cc" (without "--raw" and other forms
Re: Patches generated by "git format-patch -M -B" can't be applied with "git apply"?
Dan Kegel writes: Yes, "diff -M -B" is known to be problematic, unfortunately. It incorrectly creates an irreversible patch under certain conditions. http://thread.gmane.org/gmane.linux.kernel/1879635 -- 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: Patches generated by "git format-patch -M -B" can't be applied with "git apply"?
Yes, "diff -M -B" is known to be problematic, unfortunately. It incorrectly creates an irreversible patch under certain conditions. http://thread.gmane.org/gmane.linux.kernel/1879635 -- 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
Patches generated by "git format-patch -M -B" can't be applied with "git apply"?
A bot I wrote uses 'git format-patch -M -B' to generate a patch to send off to be applied with 'git am' on a remote machine. Alas, renames do not appear to work; git am rejects them with error: file2: already exists in working directory This happens both with the git that ships with Ubuntu 14.04 and with master ( git version 2.6.0.rc1.16.g1962994 ). I noticed that git has a similar test case already, t4130-apply-criss-cross-rename.sh so I munged that to reproduce the error, http://kegel.com/git/t4154-apply-half-criss-cross-rename.sh.txt Running ./t4154-apply-half-criss-cross-rename.sh -v fails for me reliably with error: file2: already exists in working directory with either v2.6.0-rc2 or random local git on local Mac and Linux. is this behavior indeed a bug, or am I breaking some rule? Thanks! - Dan p.s. Here's the test case inline, but if email munges whitespace, the url above might be better. #!/bin/sh test_description='git apply handling half-criss-cross rename patch.' . ./test-lib.sh create_file() { cnt=0 while test $cnt -le 100 do cnt=$(($cnt + 1)) echo "$2" >> "$1" done } test_expect_success 'setup' ' create_file file1 "File1 contents" && create_file file2 "File2 contents" && git add file1 file2 && git commit -m 1 ' test_expect_success 'half criss-cross rename' ' mv file1 file2 && git rm file1 && git add file2 && git commit -m 2 ' test_expect_success 'diff -M -B' ' git format-patch -M -B HEAD^ --stdout > diff && git reset --hard HEAD^ ' test_expect_success 'apply' ' git apply --check diff ' test_done -- 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: Developing- Where to Start
On Mon, Sep 14, 2015 at 2:30 PM, Christian Couder wrote: > Hi, > > On Mon, Sep 14, 2015 at 10:42 PM, Breanna Devore-McDonald > wrote: >> Hello all, >> >> I'm a third year Computer Science student at the University of Notre >> Dame, and for the final project of my Data Structures class, my group >> and I have to find a way to contribute our (hopefully) newly-found >> data structures and optimization knowledge to a well-known open source >> project. We thought Git would be a great project to work on, but we >> have no idea where to start. Can anyone offer ideas or parts of the >> code that we could possibly help with? (a problem that is data >> structures-related would be extremely helpful!) One problem focused around data structures may be rewriting the git bisect internal algorithm. Currently git bisect uses an O(n^2), but there are better algorithms available such as [1] [1] https://docs.google.com/document/d/1hzF8fZbsQtKwUPH60dsEwVZM2wmESFq713SeAsg_hkc/edit?usp=sharing The algorithm presented in that doc came up in a discussion between some Git developers, I just wrote it down. Maybe it's understandable. That said, usually the tests in git bisect take the most time, so it is an internal optimization related to data structures, whose impact is estimated to matter only a bit. Also I would estimate the project to rewrite git bisect to be quite a lot of effort. > > The Git project often participate in the Google Summer of Code. > > This year we used the following resources to help potential GSoC > students get involved in developing Git and find a project to work on: > > http://git.github.io/SoC-2015-Microprojects.html > http://git.github.io/SoC-2015-Ideas.html Yeah the microprojects are awesome to get into Git development! Also look at http://git-blame.blogspot.com/p/leftover-bits.html for smaller projects. > > A GSoC wrap up has been written recently in Git Rev News edition 7: > > http://git.github.io/rev_news/2015/09/09/edition-7/ > > Earlier this year students from Ensimag (Grenoble, France) also > contributed to Git and a small wrap up is available in Git Rev News > edition 5: > > http://git.github.io/rev_news/2015/07/08/edition-5/ > > I hope this will help you get started in your Git development journey. > > Best, > Christian. > -- > 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 -- 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: [PATCHv2] fetch submodules in parallel
Stefan Beller writes: > This replaces the last patch of the "Parallel git submodule fetching" > series. Changes: > > * have correct return code in submodule fetching when one submodule fails > * use poll instead of select now > * broke down into more smaller functions instead of one giant. > (I think it is an improvement, but I wouldn't be surprised if someone > objects) > * closed memory leaks > * document the need for stdout_to_stderr > > I don't deem it RFC-ish any more but good to go. I didn't say this in the previous round because it smelled like an RFC, but for a real submission, 2/2 may be doing too many things at once. I suspect this is more or less "taste" thing, so I won't mind too much as long as the reviewers are OK with it. -- 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
[PATCHv2] fetch submodules in parallel
This replaces the last patch of the "Parallel git submodule fetching" series. Changes: * have correct return code in submodule fetching when one submodule fails * use poll instead of select now * broke down into more smaller functions instead of one giant. (I think it is an improvement, but I wouldn't be surprised if someone objects) * closed memory leaks * document the need for stdout_to_stderr I don't deem it RFC-ish any more but good to go. Any feedback welcome! Thanks, Stefan Stefan Beller (1): fetch: fetch submodules in parallel Documentation/fetch-options.txt | 7 + builtin/fetch.c | 6 +- builtin/pull.c | 6 + run-command.c | 278 run-command.h | 36 ++ strbuf.c| 31 + strbuf.h| 1 + submodule.c | 119 - submodule.h | 2 +- t/t0061-run-command.sh | 20 +++ t/t5526-fetch-submodules.sh | 19 +++ test-run-command.c | 24 12 files changed, 490 insertions(+), 59 deletions(-) Interdiff to RFCv1: diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt index d432f98..6b109f6 100644 --- a/Documentation/fetch-options.txt +++ b/Documentation/fetch-options.txt @@ -105,7 +105,7 @@ ifndef::git-pull[] Number of parallel children to be used for fetching submodules. Each will fetch from different submodules, such that fetching many submodules will be faster. By default submodules will be fetched - one at a time + one at a time. --no-recurse-submodules:: Disable recursive fetching of submodules (this has the same effect as diff --git a/builtin/fetch.c b/builtin/fetch.c index a1520bb..f28eac6 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -101,7 +101,7 @@ static struct option builtin_fetch_options[] = { OPT_SET_INT('n', NULL, &tags, N_("do not fetch all tags (--no-tags)"), TAGS_UNSET), OPT_INTEGER('j', "jobs", &max_children, - N_("number of threads used for fetching")), + N_("number of submodules fetched in parallel")), OPT_BOOL('p', "prune", &prune, N_("prune remote-tracking branches no longer on remote")), { OPTION_CALLBACK, 0, "recurse-submodules", NULL, N_("on-demand"), diff --git a/builtin/pull.c b/builtin/pull.c index bc117e9..f0af196 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -179,7 +179,7 @@ static struct option pull_options[] = { N_("control recursive fetching of submodules"), PARSE_OPT_OPTARG), OPT_PASSTHRU('j', "jobs", &max_children, N_("n"), - N_("number of threads used for fetching submodules"), + N_("number of submodules pulled in parallel"), PARSE_OPT_OPTARG), OPT_BOOL(0, "dry-run", &opt_dry_run, N_("dry run")), diff --git a/run-command.c b/run-command.c index b8ff67b..6f6f9fb 100644 --- a/run-command.c +++ b/run-command.c @@ -232,6 +232,35 @@ static inline void set_cloexec(int fd) fcntl(fd, F_SETFD, flags | FD_CLOEXEC); } +static int determine_return_value(int wait_status, + int *result, + int *error_code, + const char *argv0) +{ + if (WIFSIGNALED(wait_status)) { + *result = WTERMSIG(wait_status); + if (*result != SIGINT && *result != SIGQUIT) + error("%s died of signal %d", argv0, *result); + /* +* This return value is chosen so that code & 0xff +* mimics the exit code that a POSIX shell would report for +* a program that died from this signal. +*/ + *result += 128; + } else if (WIFEXITED(wait_status)) { + *result = WEXITSTATUS(wait_status); + /* +* Convert special exit code when execvp failed. +*/ + if (*result == 127) { + *result = -1; + *error_code = ENOENT; + } + } else + return 1; + return 0; +} + static int wait_or_whine(pid_t pid, const char *argv0) { int status, code = -1; @@ -244,29 +273,10 @@ static int wait_or_whine(pid_t pid, const char *argv0) if (waiting < 0) { failed_errno = errno; error("waitpid for %s failed: %s", argv0, strerror(errno)); - } else if (waiting != pid) { - error("waitpid is confused (%s)", argv0); - } else if (WIFSIGNALED(status)) { - code = WTERMSIG(status); - if (code != SIGINT && code != SIGQUIT) - error("%s died of signal %d", argv0, code); -
[PATCHv2] fetch: fetch submodules in parallel
If we run external commands in parallel we cannot pipe the output directly to the our stdout/err as it would mix up. So each process's output will flow through a pipe, which we buffer. One subprocess can be directly piped to out stdout/err for a low latency feedback to the user. Example: Let's assume we have 5 submodules A,B,C,D,E and each fetch takes a different amount of time as the different submodules vary in size, then the output of fetches in sequential order might look like this: time --> output: |---A---| |-B-| |C---| |-D-| |-E-| When we schedule these submodules into maximal two parallel processes, a schedule and sample output over time may look like this: thread 1: |---A---| |-D-| |-E-| thread 2: |-B-| |C---| output: |---A---|B|--C---|DE So A will be perceived as it would run normally in the single child version. As B has finished by the time A is done, we can dump its whole progress buffer on stderr, such that it looks like it finished in no time. Once that is done, C is determined to be the visible child and its progress will be reported in real time. So this way of output is really good for human consumption, as it only changes the timing, not the actual output. For machine consumption the output needs to be prepared in the tasks, by either having a prefix per line or per block to indicate whose tasks output is displayed. Signed-off-by: Stefan Beller --- Documentation/fetch-options.txt | 7 + builtin/fetch.c | 6 +- builtin/pull.c | 6 + run-command.c | 278 run-command.h | 36 ++ strbuf.c| 31 + strbuf.h| 1 + submodule.c | 119 - submodule.h | 2 +- t/t0061-run-command.sh | 20 +++ t/t5526-fetch-submodules.sh | 19 +++ test-run-command.c | 24 12 files changed, 490 insertions(+), 59 deletions(-) diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt index 45583d8..6b109f6 100644 --- a/Documentation/fetch-options.txt +++ b/Documentation/fetch-options.txt @@ -100,6 +100,13 @@ ifndef::git-pull[] reference to a commit that isn't already in the local submodule clone. +-j:: +--jobs=:: + Number of parallel children to be used for fetching submodules. + Each will fetch from different submodules, such that fetching many + submodules will be faster. By default submodules will be fetched + one at a time. + --no-recurse-submodules:: Disable recursive fetching of submodules (this has the same effect as using the '--recurse-submodules=no' option). diff --git a/builtin/fetch.c b/builtin/fetch.c index ee1f1a9..f28eac6 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -37,6 +37,7 @@ static int prune = -1; /* unspecified */ static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity; static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT; static int tags = TAGS_DEFAULT, unshallow, update_shallow; +static int max_children = 1; static const char *depth; static const char *upload_pack; static struct strbuf default_rla = STRBUF_INIT; @@ -99,6 +100,8 @@ static struct option builtin_fetch_options[] = { N_("fetch all tags and associated objects"), TAGS_SET), OPT_SET_INT('n', NULL, &tags, N_("do not fetch all tags (--no-tags)"), TAGS_UNSET), + OPT_INTEGER('j', "jobs", &max_children, + N_("number of submodules fetched in parallel")), OPT_BOOL('p', "prune", &prune, N_("prune remote-tracking branches no longer on remote")), { OPTION_CALLBACK, 0, "recurse-submodules", NULL, N_("on-demand"), @@ -1217,7 +1220,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) result = fetch_populated_submodules(&options, submodule_prefix, recurse_submodules, - verbosity < 0); + verbosity < 0, + max_children); argv_array_clear(&options); } diff --git a/builtin/pull.c b/builtin/pull.c index 722a83c..f0af196 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -94,6 +94,7 @@ static int opt_force; static char *opt_tags; static char *opt_prune; static char *opt_recurse_submodules; +static char *max_children; static int opt_dry_run; static char *opt_keep; static char *opt_depth; @@ -177,6 +178,9 @@ static struct option pull_options[] = { N_("on-demand"), N_("control recursive fetching of submodules"), PARSE_OPT_OPTARG), +
Re: Developing- Where to Start
Hi, On Mon, Sep 14, 2015 at 10:42 PM, Breanna Devore-McDonald wrote: > Hello all, > > I'm a third year Computer Science student at the University of Notre > Dame, and for the final project of my Data Structures class, my group > and I have to find a way to contribute our (hopefully) newly-found > data structures and optimization knowledge to a well-known open source > project. We thought Git would be a great project to work on, but we > have no idea where to start. Can anyone offer ideas or parts of the > code that we could possibly help with? (a problem that is data > structures-related would be extremely helpful!) The Git project often participate in the Google Summer of Code. This year we used the following resources to help potential GSoC students get involved in developing Git and find a project to work on: http://git.github.io/SoC-2015-Microprojects.html http://git.github.io/SoC-2015-Ideas.html A GSoC wrap up has been written recently in Git Rev News edition 7: http://git.github.io/rev_news/2015/09/09/edition-7/ Earlier this year students from Ensimag (Grenoble, France) also contributed to Git and a small wrap up is available in Git Rev News edition 5: http://git.github.io/rev_news/2015/07/08/edition-5/ I hope this will help you get started in your Git development journey. Best, Christian. -- 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
Developing- Where to Start
Hello all, I'm a third year Computer Science student at the University of Notre Dame, and for the final project of my Data Structures class, my group and I have to find a way to contribute our (hopefully) newly-found data structures and optimization knowledge to a well-known open source project. We thought Git would be a great project to work on, but we have no idea where to start. Can anyone offer ideas or parts of the code that we could possibly help with? (a problem that is data structures-related would be extremely helpful!) Many thanks, Breanna Devore-McDonald -- 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] strtoul_ui: actually report error in case of negative input
On Mon, Sep 14, 2015 at 08:30:54AM +0200, Matthieu Moy wrote: >> Fix it by changing the last check to trigger earlier, as soon as it >> becomes bigger than INT_MAX. > > What if the value is actually greater than INT_MAX? The function is > returning an unsigned long (64 bits on 64bits architectures), and your > version is restricting it to integers smaller than 2^31, right? the return type of the function is "int", so this is not going to work anyway. As I mentioned, some negative values are still accepted as coresponding mod 2**32 positive numbers (-3221225472 as 1073741824), so there really is room for improvement, but it cannot be accomplished just by examining strtoul output. I saw in the list archives an attempt to abandon the function in favor of more accurate parser [1], but seems like it did not make it into the project. [1] http://thread.gmane.org/gmane.comp.version-control.git/265635 -- Max -- 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 5/8] branch: drop non-commit error reporting
Karthik Nayak writes: > Remove the error reporting variable to make the code easier to port > over to using ref-filter APIs. This variable is not required as in > ref-filter we already check for possible errors and report them. H. What do you exactly mean "possible errors" here? Unlike generic refs that can point at anything, refs/heads/* refs must point at a commit [*1*], and that is why the error message says 'does not point at a commit'. Does ref-filter API have corresponding check to treat the local and remote branch hierarchies differently from tags and others? [Footnote] *1* Strictly speaking, use of lookup_commit_reference_gently() in the existing code allows a committish to be there and does not limit the tip objects to be commits, but I think it is a bug. At least, even with deref_tag(), we reject non committish found at the tip of branch refs and explain with the error message this patch removes. > Based-on-patch-by: Jeff King > Mentored-by: Christian Couder > Mentored-by: Matthieu Moy > Signed-off-by: Karthik Nayak > --- > builtin/branch.c | 18 -- > 1 file changed, 4 insertions(+), 14 deletions(-) > > diff --git a/builtin/branch.c b/builtin/branch.c > index 4d9e4d0..8b9da60 100644 > --- a/builtin/branch.c > +++ b/builtin/branch.c > @@ -313,7 +313,6 @@ static char *resolve_symref(const char *src, const char > *prefix) > struct append_ref_cb { > struct ref_list *ref_list; > const char **pattern; > - int ret; > }; > > static int match_patterns(const char **pattern, const char *refname) > @@ -370,10 +369,8 @@ static int append_ref(const char *refname, const struct > object_id *oid, int flag > commit = NULL; > if (ref_list->verbose || ref_list->with_commit || merge_filter != > NO_FILTER) { > commit = lookup_commit_reference_gently(oid->hash, 1); > - if (!commit) { > - cb->ret = error(_("branch '%s' does not point at a > commit"), refname); > + if (!commit) > return 0; > - } > > /* Filter with with_commit if specified */ > if (!is_descendant_of(commit, ref_list->with_commit)) > @@ -617,7 +614,7 @@ static int calc_maxwidth(struct ref_list *refs, int > remote_bonus) > return max; > } > > -static int print_ref_list(int kinds, int detached, int verbose, int abbrev, > struct commit_list *with_commit, const char **pattern) > +static void print_ref_list(int kinds, int detached, int verbose, int abbrev, > struct commit_list *with_commit, const char **pattern) > { > int i, index; > struct append_ref_cb cb; > @@ -642,7 +639,6 @@ static int print_ref_list(int kinds, int detached, int > verbose, int abbrev, stru > init_revisions(&ref_list.revs, NULL); > cb.ref_list = &ref_list; > cb.pattern = pattern; > - cb.ret = 0; > /* >* First we obtain all regular branch refs and if the HEAD is >* detached then we insert that ref to the end of the ref_fist > @@ -702,11 +698,6 @@ static int print_ref_list(int kinds, int detached, int > verbose, int abbrev, stru > abbrev, detached, remote_prefix); > > free_ref_list(&ref_list); > - > - if (cb.ret) > - error(_("some refs could not be read")); > - > - return cb.ret; > } > > static void rename_branch(const char *oldname, const char *newname, int > force) > @@ -922,15 +913,14 @@ int cmd_branch(int argc, const char **argv, const char > *prefix) > die(_("branch name required")); > return delete_branches(argc, argv, delete > 1, kinds, quiet); > } else if (list) { > - int ret; > /* git branch --local also shows HEAD when it is detached */ > if (kinds & REF_LOCAL_BRANCH) > kinds |= REF_DETACHED_HEAD; > - ret = print_ref_list(kinds, detached, verbose, abbrev, > + print_ref_list(kinds, detached, verbose, abbrev, >with_commit, argv); > print_columns(&output, colopts, NULL); > string_list_clear(&output, 0); > - return ret; > + return 0; > } > else if (edit_description) { > const char *branch_name; -- 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 3/8] branch: roll show_detached HEAD into regular ref_list
Karthik Nayak writes: > + /* > + * First we obtain all regular branch refs and if the HEAD is > + * detached then we insert that ref to the end of the ref_fist > + * so that it can be printed and removed first. > + */ > for_each_rawref(append_ref, &cb); > + if (detached) > + head_ref(append_ref, &cb); > + index = ref_list.index; > + > + /* Print detached HEAD before sorting and printing the rest */ > + if (detached && (ref_list.list[index - 1].kind == REF_DETACHED_HEAD) && > + !strcmp(ref_list.list[index - 1].name, head)) { > + print_ref_item(&ref_list.list[index - 1], maxwidth, verbose, > abbrev, > +1, remote_prefix); > + index -= 1; > + } > > + qsort(ref_list.list, index, sizeof(struct ref_item), ref_cmp); This looks somewhat strange. Wouldn't it be more consistent to teach ref_cmp that HEAD sorts where in the collection of refs (I presume that kind is checked first and then name, so if you give REF_DETACHED_HEAD a low number than others, it would automatically give you the ordering you want) without all of the above special casing? -- 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] gitk: accelerators for the main menu
Paul Mackerras writes: > On Wed, Sep 09, 2015 at 03:20:53PM +0200, Giuseppe Bilotta wrote: >> This allows fast, keyboard-only usage of the menu (e.g. Alt+V, N to open a >> new view). >> >> Signed-off-by: Giuseppe Bilotta > > Thanks, applied. Thanks; will pull from you before tagging 2.6-rc2. -- 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 v7] git-p4: improve path encoding verbose output
larsxschnei...@gmail.com writes: > From: Lars Schneider > > If a path with non-ASCII characters is detected then print always the > encoding and the encoded string in verbose mode. Earlier if the user tells us that s/he knows what she is doing by setting the configuration, we just followed the instruction without complaining or notifying. The differences in this version are (1) if the path is in ASCII, the configuration is not even consulted, and we didn't do any path munging. (2) for a non-ASCII path, even if the user tells us that s/he knows what she is doing, we notify what we did under "--verbose" mode. I think (1) is a definite improvement, but it is not immediately obvious why (2) is an improvement. It is clearly a good thing to let the user know when we munged the path without being told, but when the configuration is given, it can be argued both ways. It may be a good thing to reassure that the configuration is kicking in, or it may be a needless noise to tell the user that we did what we were told to do. In any case, I suspectq that the call to decode-encode to munge relPath is indented one level too deep in this patch. You would want to use the configured value if exists and utf8 if there is no configuration, but in either case you would want to munge relPath when it does not decode as ASCII, no? > Signed-off-by: Lars Schneider > --- > git-p4.py | 19 +-- > 1 file changed, 9 insertions(+), 10 deletions(-) > > diff --git a/git-p4.py b/git-p4.py > index d45cf2b..da25d3f 100755 > --- a/git-p4.py > +++ b/git-p4.py > @@ -2220,16 +2220,15 @@ class P4Sync(Command, P4UserMap): > text = regexp.sub(r'$\1$', text) > contents = [ text ] > > -if gitConfig("git-p4.pathEncoding"): > -relPath = > relPath.decode(gitConfig("git-p4.pathEncoding")).encode('utf8', 'replace') > -elif self.verbose: > -try: > -relPath.decode('ascii') > -except: > -print ( > -"Path with Non-ASCII characters detected and no path > encoding defined. " > -"Please check the encoding: %s" % relPath > -) > +try: > +relPath.decode('ascii') > +except: > +encoding = 'utf8' > +if gitConfig('git-p4.pathEncoding'): > +encoding = gitConfig('git-p4.pathEncoding') > +relPath = relPath.decode(encoding).encode('utf8', 'replace') > +if self.verbose: > +print 'Path with non-ASCII characters detected. Used %s to > encode: %s ' % (encoding, relPath) > > self.gitStream.write("M %s inline %s\n" % (git_mode, relPath)) -- 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 v7] git-p4: add config git-p4.pathEncoding
larsxschnei...@gmail.com writes: > From: Lars Schneider > > diff to v6: > * Always print the encoded path in verbose mode. > > v6 is already on next (a9e383). This patch must be applied on next. > Is this the right way to handle this situation? Yes, I thought that the reviewers found v6 was solid enough, and it is now in 'next'. It is best to do further polishing on the tip of the topic that is in 'next', i.e. a9e38359 (git-p4: add config git-p4.pathEncoding, 2015-09-03). Labeling the patch as v7 is misleading, but from the context (like your cover letter description) it was clear that the patch is a follow-up, so everything looks good from procedural point of view. Thanks for making reviewer's life easier. -- 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 v8 0/2] Submodule object path
Max Kirillov writes: > On Thu, Sep 10, 2015 at 06:10:13PM -0700, Junio C Hamano wrote: >> When I push the updated 'pu' out, could you please check > > I follow the pu merges. So far resolutions seem correct and > all tests pass. The primary thing I ask from "eyeballing by the original author" is to see if "git diff M^ M" for the merge M of the topic is something the original author would have done if he was given a starting point of M^ to build his or her topic (which is what your "resolutions seem correct" really is), so we are good. > If you don't mind re-resolving it as I send newer versions I will > base them on master. So far rerere seems to be happy, so basing on the same commit is fine, but I suspect this round should already be ready for 'next'. I had to remove the now-unused variable "const char *git_dir;" in [PATCH 1/2], but other than that it looked OK from a cursory re-read. Thanks. -- 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 2/2] fetch: fetch submodules in parallel
On Mon, Sep 14, 2015 at 10:55:09AM -0700, Jonathan Nieder wrote: > > I don't think you need exact timing information. This is no different > > than running the commands themselves, with stdout and stderr writing to > > a pty that your terminal emulator will then read() from. If the program > > produces intermingled stdout/stderr that clogs up the terminal, that is > > its problem. > > The difference is that when stdout and stderr write to a pty, they write > to the same pty. That is, suppose a child process does > > write(1, "A\n", 2); > write(2, "B\n", 1); > write(1, "C\n", 2); Ah, right. The pty is where things get mixed, not the read() from the terminal. So it depends on the write() order. Thanks for the explanation. > One can imagine a "git grep --recurse-submodules" that wants to run a > grep in each submodule and combine their output in some appropriate > way. It's not clear what order is best for that use case: stderr > (errors, plus progress in some imaginary future) at the beginning to > show the story of how output was generated before the output? stderr > at the end so errors are not hidden way up on the screen? Some kind > of interleaving that pays attention to the format of stdout? I'd suggest a "best effort" interleaving, where we select and preserve the read() order. That makes the easy cases work (you get things in the original order), and the hard cases at least do something reasonable (we may reorder two items which come in the same atomic "tick" of our select, but at least they are nearby). That's just my gut feeling, though. > That is more complicated than the "fetch --recurse-submodules" case > that Stefan is currently tackling, so it seems wise to me to punt for > now. I can live with that. -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: [PATCH v9 1/2] submodule refactor: use strbuf_git_path_submodule() in add_submodule_odb()
Max Kirillov writes: > Functions which directly operate submodule's object database do not > handle the case when the submodule is linked worktree (which are > introduced in c7b3a3d2fe). Instead of fixing the path calculation use > already existing strbuf_git_path_submodule() function without changing > overall behaviour. Then it will be possible to modify only that function > whenever we need to change real location of submodule's repository > content. > > Edited-by: Jeff King > Signed-off-by: Max Kirillov > --- > submodule.c | 8 +--- > 1 file changed, 1 insertion(+), 7 deletions(-) This certainly is a lot nicer ;-) Thanks. > > diff --git a/submodule.c b/submodule.c > index 245ed4d..16b7c35 100644 > --- a/submodule.c > +++ b/submodule.c > @@ -124,13 +124,7 @@ static int add_submodule_odb(const char *path) > int ret = 0; > const char *git_dir; > > - strbuf_addf(&objects_directory, "%s/.git", path); > - git_dir = read_gitfile(objects_directory.buf); > - if (git_dir) { > - strbuf_reset(&objects_directory); > - strbuf_addstr(&objects_directory, git_dir); > - } > - strbuf_addstr(&objects_directory, "/objects/"); > + strbuf_git_path_submodule(&objects_directory, path, "objects/"); > if (!is_directory(objects_directory.buf)) { > ret = -1; > goto done; -- 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 2/2] fetch: fetch submodules in parallel
Jeff King writes: > I don't think you need exact timing information. This is no different > than running the commands themselves, with stdout and stderr writing to > a pty that your terminal emulator will then read() from. If the program > produces intermingled stdout/stderr that clogs up the terminal, that is > its problem. > > The only difference is that we're going to save it and later replay it > all very quickly. So I think it would be sufficient just to retain the > original order. > >> I will add documentation explaining why the async output case >> will only deal with one channel. I chose stderr as that's already >> available and needed in this use case. > > I suspect you could just set child->stdout_to_stderr in this case, and > then you get your ordering for free. I think we are in agreement; that is exactly what I wanted to say when I said "I offhand do not think the latter [i.e. the callers have to dup them together] is unreasonable". Thanks for stating it more clearly and explicitly. > To handle multiple channels, I think you could just do a linked list of > buffers rather than a single strbuf. Like: > > struct io_chunk { > int channel; > char *buf; > size_t len; > struct io_chunk *next; > }; > > and just keep appending chunks to the list (and to dump them, just walk > the list, writing each to the appropriate channel descriptor). Perhaps, but let's not overdesign things before we have a concrete example codepath that benefits from such a thing. It is hard to detect a misdesign without a real usage pattern. -- 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 2/2] fetch: fetch submodules in parallel
Jeff King wrote: > On Mon, Sep 14, 2015 at 09:46:58AM -0700, Stefan Beller wrote: >> I tried implementing a buffering solution for both stdout and stderr, >> but that doesn't really workout well if you consider interleaved output >> on the pipes as we cannot accurately replay that later on. [...] >> obtaining the information is inherently racy [...] > I don't think you need exact timing information. This is no different > than running the commands themselves, with stdout and stderr writing to > a pty that your terminal emulator will then read() from. If the program > produces intermingled stdout/stderr that clogs up the terminal, that is > its problem. The difference is that when stdout and stderr write to a pty, they write to the same pty. That is, suppose a child process does write(1, "A\n", 2); write(2, "B\n", 1); write(1, "C\n", 2); Then the output that should be echoed to the terminal is A B C Now the parent might do for (;;) { int n = select(...); ... do stuff ... } If all three writes happen during the "do stuff" step, then *if* the child's stdout and stderr went to different pipes, all the parent sees is child's stdout: A\nC\n child's stderr: B\n There is not sufficient information to recover the original output order. (Linux provides a pipe2(..., O_DIRECT) that almost provides sufficient information --- it tells you child's stdout: "A\n", "C\n" child's stderr: "B\n" but still doesn't give information about ordering.) That's probably okay: in most git commands, stderr shows a combination of diagnostic output and progress information and stdout shows the actual result, so interleaving between the two is not too common. One can imagine a "git grep --recurse-submodules" that wants to run a grep in each submodule and combine their output in some appropriate way. It's not clear what order is best for that use case: stderr (errors, plus progress in some imaginary future) at the beginning to show the story of how output was generated before the output? stderr at the end so errors are not hidden way up on the screen? Some kind of interleaving that pays attention to the format of stdout? That is more complicated than the "fetch --recurse-submodules" case that Stefan is currently tackling, so it seems wise to me to punt for now. Thanks and hope that helps, Jonathan -- 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 2/2] fetch: fetch submodules in parallel
On Mon, Sep 14, 2015 at 10:17 AM, Jeff King wrote: > On Mon, Sep 14, 2015 at 09:46:58AM -0700, Stefan Beller wrote: > >> I tried implementing a buffering solution for both stdout and stderr, >> but that doesn't really workout well if you consider interleaved output >> on the pipes as we cannot accurately replay that later on. To do that >> we would need to store the timing information of the channels, at least >> the relative order of it like: >> >> (stdout, First comes text to stdout), >> (stderr, interrupted by text in stderr) >> (stdout, but stdout doesn't bother, blasting more text) >> (stderr, continues to interrupt) >> >> obtaining the information is inherently racy, as all we can do is >> polling/reading from both stdout/err as fast as possible but without >> proper synchronization mechanisms we cannot be sure. > > I don't think you need exact timing information. This is no different > than running the commands themselves, with stdout and stderr writing to > a pty that your terminal emulator will then read() from. If the program > produces intermingled stdout/stderr that clogs up the terminal, that is > its problem. > > The only difference is that we're going to save it and later replay it > all very quickly. So I think it would be sufficient just to retain the > original order. > >> I will add documentation explaining why the async output case >> will only deal with one channel. I chose stderr as that's already >> available and needed in this use case. > > I suspect you could just set child->stdout_to_stderr in this case, and > then you get your ordering for free. But probably in the general case > people would want to run inspection commands that produce a useful > stdout. > > To handle multiple channels, I think you could just do a linked list of > buffers rather than a single strbuf. Like: I will have no problem coding such a thing in a user program, but how do you obtain this non racily from the child using the posix API? The poll/select command may return more than one fd ready, so then you don't know the ordering in which you would need to replay it. This may introduce subtle bugs? So I'd rather come up with a solution buffering 2 channels once we need it, keeping the stdout_to_stderr as a requirement for now. > > struct io_chunk { > int channel; > char *buf; > size_t len; > struct io_chunk *next; > }; > > and just keep appending chunks to the list (and to dump them, just walk > the list, writing each to the appropriate channel descriptor). > > -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: [PATCH v7 2/3] worktree: move/refactor find_shared_symref from branch.c
On Sat, Sep 12, 2015 at 11:19 PM, Eric Sunshine wrote: > On Fri, Sep 4, 2015 at 5:39 PM, Michael Rappazzo wrote: >> The code formerly in branch.c was largely the basis of the >> get_worktree_list implementation is now moved to worktree.c, >> and the find_shared_symref implementation has been refactored >> to use get_worktree_list > > Some comments below in addition to those by Junio... > >> Signed-off-by: Michael Rappazzo >> --- >> diff --git a/branch.h b/branch.h >> index d3446ed..58aa45f 100644 >> --- a/branch.h >> +++ b/branch.h >> @@ -59,12 +59,4 @@ extern int read_branch_desc(struct strbuf *, const char >> *branch_name); >> */ >> extern void die_if_checked_out(const char *branch); >> >> -/* >> - * Check if a per-worktree symref points to a ref in the main worktree >> - * or any linked worktree, and return the path to the exising worktree >> - * if it is. Returns NULL if there is no existing ref. The caller is >> - * responsible for freeing the returned path. >> - */ >> -extern char *find_shared_symref(const char *symref, const char *target); >> - >> #endif >> diff --git a/worktree.c b/worktree.c >> index 33d2e57..e45b651 100644 >> --- a/worktree.c >> +++ b/worktree.c >> @@ -155,3 +155,43 @@ done: >> return list; >> } >> >> +char *find_shared_symref(const char *symref, const char *target) >> +{ >> + char *existing = NULL; >> + struct strbuf path = STRBUF_INIT; >> + struct strbuf sb = STRBUF_INIT; >> + struct worktree_list *worktree_list = get_worktree_list(); >> + struct worktree_list *orig_list = worktree_list; >> + struct worktree *matched = NULL; >> + >> + while (!matched && worktree_list) { >> + if (strcmp("HEAD", symref)) { > > The result of strcmp() never changes, so this (expensive) check could > be lifted out of the 'while' loop, however... > >> + strbuf_reset(&path); >> + strbuf_reset(&sb); >> + strbuf_addf(&path, "%s/%s", >> worktree_list->worktree->git_dir, symref); >> + >> + if (_parse_ref(path.buf, &sb, NULL)) { >> + continue; >> + } >> + >> + if (!strcmp(sb.buf, target)) >> + matched = worktree_list->worktree; > > The original code in branch.c, which this patch removes, did not need > to make a special case of HEAD, so it's not immediately clear why this > replacement code does so. This is the sort of issue which argues in > favor of mutating the existing code (slowly) over the course of > several patches into the final form, rather than having the final form > come into existence out of thin air. When the changes are made > incrementally, it is easier for reviewers to understand why such > modifications are needed, which (hopefully) should lead to fewer > questions such as this one. > I reversed the the check here; it is intended to check if the symref is _not_ the head, since the head ref has already been parsed. This is used in notes.c to find "NOTES_MERGE_REF". I will move the check out of the loop as you suggest above. >> + } else { >> + if (worktree_list->worktree->head_ref && >> !strcmp(worktree_list->worktree->head_ref, target)) >> + matched = worktree_list->worktree; >> + } >> + worktree_list = worktree_list->next ? worktree_list->next : >> NULL; >> + } >> + >> + if (matched) { >> + existing = malloc(strlen(matched->path) + 1); >> + strcpy(existing, matched->path); > > A couple issues: > > This can be done more concisely and safely with xstrdup(). > > In this codebase, it probably would be more idiomatic to use goto to > drop out of the loop rather than setting 'matched' and then having to > check 'matched' in the loop condition. So, for instance, each place > which sets 'matched' could instead say: > > existing = xstrdup(...); > goto done; > >> + } >> + >> +done: > > This label doesn't have any matching goto's. > >> + strbuf_release(&path); >> + strbuf_release(&sb); >> + worktree_list_release(orig_list); >> + >> + return existing; >> +} >> diff --git a/worktree.h b/worktree.h >> index 2bc0ab8..320f17e 100644 >> --- a/worktree.h >> +++ b/worktree.h >> @@ -45,4 +45,11 @@ struct worktree *get_worktree(const char *id); >> extern void worktree_list_release(struct worktree_list *); >> extern void worktree_release(struct worktree *); >> >> +/* >> + * Look for a symref in any worktree, and return the path to the first >> + * worktree found or NULL if not found. The caller is responsible for >> + * freeing the returned path. >> + */ > > For some reason, this comment differs a fair bit from the original in > branch.h which was removed by this patch, however, the original > comment was a bit more explanatory (I think). > > As a general rule, it's be
Re: [PATCH v7 1/3] worktree: add top-level worktree.c
Mike Rappazzo writes: > On Sat, Sep 12, 2015 at 10:39 PM, Eric Sunshine > wrote: >>> +struct worktree_list *get_worktree_list() >> >> Can we be more concise and call this get_worktrees()? > > I prefer 'get_worktree_list' because I also added the 'get_worktree' > function, and I wanted to differentiate > the function names. I'd say that plural can be differentiating enough; it probably is a matter of taste. How often do external callers want to call get_worktree() and not get_worktrees()? >>> diff --git a/worktree.h b/worktree.h >>> new file mode 100644 >>> index 000..2bc0ab8 >>> --- /dev/null >>> +++ b/worktree.h >>> @@ -0,0 +1,48 @@ >>> +#ifndef WORKTREE_H >>> +#define WORKTREE_H >>> + >>> +struct worktree { >>> + char *path; >>> + char *git_dir; >>> + char *head_ref; >>> + unsigned char head_sha1[20]; >>> + int is_detached; >>> + int is_bare; >>> +}; >>> + >>> +struct worktree_list { >>> + struct worktree *worktree; >>> + struct worktree_list *next; >>> +}; >> >> I don't care too strongly, but an alternate approach (which I probably >> would have taken) would be to have get_worktrees() simply return an >> array of 'struct worktree' objects, hence no need for the additional >> 'struct worktree_list'. I do not think we are using this to hold thousands of worktree objects in core. Adding "struct worktree *next" pointer to the worktree object itself would probably be sufficient for the need of codepaths that want to enumerate and iterate over them and that would be another way to lose the extra structure. -- 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] gc: save log from daemonized gc --auto and print it next time
Junio C Hamano writes: > Thanks, will queue. Ehh, I spoke a bit too early. >> diff --git a/builtin/gc.c b/builtin/gc.c >> index bcc75d9..2c3aaeb 100644 >> --- a/builtin/gc.c >> +++ b/builtin/gc.c >> @@ -43,9 +43,20 @@ static struct argv_array prune_worktrees = >> ARGV_ARRAY_INIT; >> static struct argv_array rerere = ARGV_ARRAY_INIT; >> >> static char *pidfile; >> +static struct strbuf log_filename = STRBUF_INIT; >> +static int daemonized; >> >> static void remove_pidfile(void) >> { >> +if (daemonized && log_filename.len) { >> +struct stat st; >> + >> +close(2); >> +if (stat(log_filename.buf, &st) || >> +!st.st_size || >> +rename(log_filename.buf, git_path("gc.log"))) >> +unlink(log_filename.buf); >> +} Unfortuantely we cannot queue this as-is, as we let the tempfile API to automatically manage the pidfile since ebebeaea (gc: use tempfile module to handle gc.pid file, 2015-08-10), and you cannot piggy-back the log file finalization to this function that no longer exists. Besides, it is obviously wrong to remove this log file in a function whose name is remove_pidfile() ;-) Adding a new function to tempfile API that puts the file to a final place if it is non-empty and otherwise remove it, and using that to create this "gc.log" file, would be the cleanest from the point of view of _this_ codepath. I however do not know if that is too specific for the need of this codepath or "leave it if non-empty, but otherwise remove as it is uninteresting" is fairly common thing we would want and it is a good addition to the API set. Michael, what do you think? >> @@ -330,13 +341,21 @@ int cmd_gc(int argc, const char **argv, const char >> *prefix) >> fprintf(stderr, _("See \"git help gc\" for manual >> housekeeping.\n")); >> } >> if (detach_auto) { >> +struct strbuf sb = STRBUF_INIT; >> +if (strbuf_read_file(&sb, git_path("gc.log"), 0) > 0) >> +return error(_("last gc run reported:\n" >> + "%s\n" >> + "not running until %s is >> removed"), >> + sb.buf, git_path("gc.log")); >> +strbuf_release(&sb); >> + >> if (gc_before_repack()) >> return -1; >> /* >> * failure to daemonize is ok, we'll continue >> * in foreground >> */ >> -daemonize(); >> +daemonized = !daemonize(); >> } >> } else >> add_repack_all_option(); >> @@ -349,6 +368,18 @@ int cmd_gc(int argc, const char **argv, const char >> *prefix) >> name, (uintmax_t)pid); >> } >> >> +if (daemonized) { >> +int fd; >> + >> +strbuf_addstr(&log_filename, git_path("gc.log_XX")); >> +fd = xmkstemp(log_filename.buf); >> +if (fd >= 0) { >> +dup2(fd, 2); >> +close(fd); >> +} else >> +strbuf_release(&log_filename); >> +} >> + >> if (gc_before_repack()) >> 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
Re: [PATCH v2] l10n: de.po: translate 123 new messages
Acked-by: Phillip Sz > Signed-off-by: Ralf Thielow > --- > po/de.po | 395 > ++- > 1 file changed, 188 insertions(+), 207 deletions(-) > > diff --git a/po/de.po b/po/de.po > index b6fa9b4..7354c59 100644 > --- a/po/de.po > +++ b/po/de.po > @@ -33,19 +33,18 @@ msgstr "" > > #: advice.c:101 builtin/merge.c:1227 > msgid "You have not concluded your merge (MERGE_HEAD exists)." > msgstr "Sie haben Ihren Merge nicht abgeschlossen (MERGE_HEAD existiert)." > > #: advice.c:103 > -#, fuzzy > msgid "Please, commit your changes before you can merge." > -msgstr "Bitte gebe die Versionsbeschreibung für deine Änderungen ein." > +msgstr "Bitte committen Sie Ihre Änderungen, bevor Sie den Merge ausführen." > > #: advice.c:104 > msgid "Exiting because of unfinished merge." > -msgstr "" > +msgstr "Beende wegen nicht abgeschlossenem Merge." > > #: archive.c:12 > msgid "git archive [] [...]" > msgstr "git archive [] [...]" > > #: archive.c:13 > @@ -1084,25 +1083,25 @@ msgstr "" > #: builtin/merge.c:983 > #, c-format > msgid "Could not open '%s' for writing" > msgstr "Konnte '%s' nicht zum Schreiben öffnen." > > #: refs.c:3001 > -#, fuzzy, c-format > +#, c-format > msgid "could not delete reference %s: %s" > -msgstr "Konnte %s nicht entfernen" > +msgstr "Konnte Referenz %s nicht entfernen: %s" > > #: refs.c:3004 > -#, fuzzy, c-format > +#, c-format > msgid "could not delete references: %s" > -msgstr "Konnte %s nicht entfernen" > +msgstr "Konnte Referenzen nicht entfernen: %s" > > #: refs.c:3013 > -#, fuzzy, c-format > +#, c-format > msgid "could not remove reference %s" > -msgstr "Konnte Branch %s nicht löschen" > +msgstr "Konnte Referenz %s nicht löschen" > > #: ref-filter.c:660 > msgid "unable to parse format" > msgstr "Konnte Format nicht parsen." > > #: remote.c:792 > @@ -1228,20 +1227,19 @@ msgstr[1] "" > msgid " (use \"git pull\" to merge the remote branch into yours)\n" > msgstr "" > " (benutzen Sie \"git pull\", um Ihren Branch mit dem Remote-Branch " > "zusammenzuführen)\n" > > #: revision.c:2198 > -#, fuzzy > msgid "your current branch appears to be broken" > -msgstr "Sie sind auf einem Branch, der noch geboren wird" > +msgstr "Ihr aktueller Branch scheint fehlerhaft zu sein." > > #: revision.c:2201 > -#, fuzzy, c-format > +#, c-format > msgid "your current branch '%s' does not have any commits yet" > -msgstr "Branch '%s' zeigt auf keinen Commit" > +msgstr "Ihr aktueller Branch '%s' hat noch keine Commits." > > #: revision.c:2395 > msgid "--first-parent is incompatible with --bisect" > msgstr "Die Optionen --first-parent und --bisect sind inkompatibel." > > #: run-command.c:83 > @@ -1260,18 +1258,18 @@ msgstr "Fehler beim Signieren des > \"push\"-Zertifikates" > #: send-pack.c:404 > msgid "the receiving end does not support --signed push" > msgstr "" > "die Gegenseite unterstützt keinen signierten Versand (\"--signed push\")" > > #: send-pack.c:406 > -#, fuzzy > msgid "" > "not sending a push certificate since the receiving end does not support --" > "signed push" > msgstr "" > -"die Gegenseite unterstützt keinen signierten Versand (\"--signed push\")" > +"kein Versand des \"push\"-Zertifikates, da die Gegenseite keinen > signierten\n" > +"Versand (\"--signed push\") unterstützt" > > #: send-pack.c:418 > msgid "the receiving end does not support --atomic push" > msgstr "die Gegenseite unterstützt keinen atomaren Versand (\"--atomic > push\")" > > #: sequencer.c:183 > @@ -1311,13 +1309,13 @@ msgstr "" > msgid "Your local changes would be overwritten by revert." > msgstr "Ihre lokalen Änderungen würden von \"revert\" überschrieben werden." > > #: sequencer.c:222 > msgid "Commit your changes or stash them to proceed." > msgstr "" > -"Tragen Sie Ihre Änderungen ein oder benutzen Sie \"stash\", um > fortzufahren." > +"Committen Sie Ihre Änderungen oder benutzen Sie \"stash\", um fortzufahren." > > #. TRANSLATORS: %s will be "revert" or "cherry-pick" > #: sequencer.c:309 > #, c-format > msgid "%s: Unable to write new index file" > msgstr "%s: Konnte neue Index-Datei nicht schreiben" > @@ -1594,15 +1592,15 @@ msgstr "Konnte Eingabe-Datei '%s' nicht lesen" > > #: trailer.c:704 > msgid "could not read from stdin" > msgstr "konnte nicht von der Standard-Eingabe lesen" > > #: transport-helper.c:1025 > -#, fuzzy, c-format > +#, c-format > msgid "Could not read ref %s" > -msgstr "Konnte %s nicht lesen." > +msgstr "Konnte Referenz %s nicht lesen." > > #: unpack-trees.c:203 > msgid "Checking out files" > msgstr "Checke Dateien aus" > > #: urlmatch.c:120 > @@ -1632,18 +1630,18 @@ msgstr "ungültige Portnummer" > > #: urlmatch.c:322 > msgid "invalid '..' path segment" > msgstr "ungültiges '..' Pfadsegment" > > #: wrapper.c:219 wrapper.c:362 > -#, fuzzy, c-format > +#, c-format > msgid "could not open '%s' for reading and writing" > -msgstr "
Re: [PATCH v4] gc: save log from daemonized gc --auto and print it next time
Nguyễn Thái Ngọc Duy writes: > While commit 9f673f9 (gc: config option for running --auto in > background - 2014-02-08) helps reduce some complaints about 'gc > --auto' hogging the terminal, it creates another set of problems. > > The latest in this set is, as the result of daemonizing, stderr is > closed and all warnings are lost. This warning at the end of cmd_gc() > is particularly important because it tells the user how to avoid "gc > --auto" running repeatedly. Because stderr is closed, the user does > not know, naturally they complain about 'gc --auto' wasting CPU. > > Daemonized gc now saves stderr to $GIT_DIR/gc.log. Following gc --auto > will not run and gc.log printed out until the user removes gc.log. > > Signed-off-by: Nguyễn Thái Ngọc Duy > --- > When gc.log exists, gc --auto now simply exits > > builtin/gc.c | 33 - > 1 file changed, 32 insertions(+), 1 deletion(-) Thanks, will queue. This is sufficient for non-novice users, but I wonder if the error message is strong enough. A knee-jerk reaction to "Last run reported an error so we won't run until the log is removed" may be "Then why don't you remove the log for me automatically?", which is a total brain-less raction [*1*], and "then I'll remove the log" is not all that better. The message we want to convey is "correct the root cause so that gc can run without having to give an error message." I guess it all depends on what is in gc.log; after all, this new codepath is not in a good position to read the diagnosis left in there and offer good pieces of advice to resolve them. [Footnote] *1* ... which is what a knee-jerk reaction is by definition. > > diff --git a/builtin/gc.c b/builtin/gc.c > index bcc75d9..2c3aaeb 100644 > --- a/builtin/gc.c > +++ b/builtin/gc.c > @@ -43,9 +43,20 @@ static struct argv_array prune_worktrees = ARGV_ARRAY_INIT; > static struct argv_array rerere = ARGV_ARRAY_INIT; > > static char *pidfile; > +static struct strbuf log_filename = STRBUF_INIT; > +static int daemonized; > > static void remove_pidfile(void) > { > + if (daemonized && log_filename.len) { > + struct stat st; > + > + close(2); > + if (stat(log_filename.buf, &st) || > + !st.st_size || > + rename(log_filename.buf, git_path("gc.log"))) > + unlink(log_filename.buf); > + } > if (pidfile) > unlink(pidfile); > } > @@ -330,13 +341,21 @@ int cmd_gc(int argc, const char **argv, const char > *prefix) > fprintf(stderr, _("See \"git help gc\" for manual > housekeeping.\n")); > } > if (detach_auto) { > + struct strbuf sb = STRBUF_INIT; > + if (strbuf_read_file(&sb, git_path("gc.log"), 0) > 0) > + return error(_("last gc run reported:\n" > +"%s\n" > +"not running until %s is > removed"), > + sb.buf, git_path("gc.log")); > + strbuf_release(&sb); > + > if (gc_before_repack()) > return -1; > /* >* failure to daemonize is ok, we'll continue >* in foreground >*/ > - daemonize(); > + daemonized = !daemonize(); > } > } else > add_repack_all_option(); > @@ -349,6 +368,18 @@ int cmd_gc(int argc, const char **argv, const char > *prefix) > name, (uintmax_t)pid); > } > > + if (daemonized) { > + int fd; > + > + strbuf_addstr(&log_filename, git_path("gc.log_XX")); > + fd = xmkstemp(log_filename.buf); > + if (fd >= 0) { > + dup2(fd, 2); > + close(fd); > + } else > + strbuf_release(&log_filename); > + } > + > if (gc_before_repack()) > 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 v2] l10n: de.po: translate 123 new messages
Translate 123 new messages came from git.pot update in df0617b (l10n: git.pot: v2.6.0 round 1 (123 new, 41 removed)). Signed-off-by: Ralf Thielow --- po/de.po | 395 ++- 1 file changed, 188 insertions(+), 207 deletions(-) diff --git a/po/de.po b/po/de.po index b6fa9b4..7354c59 100644 --- a/po/de.po +++ b/po/de.po @@ -33,19 +33,18 @@ msgstr "" #: advice.c:101 builtin/merge.c:1227 msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "Sie haben Ihren Merge nicht abgeschlossen (MERGE_HEAD existiert)." #: advice.c:103 -#, fuzzy msgid "Please, commit your changes before you can merge." -msgstr "Bitte gebe die Versionsbeschreibung für deine Änderungen ein." +msgstr "Bitte committen Sie Ihre Änderungen, bevor Sie den Merge ausführen." #: advice.c:104 msgid "Exiting because of unfinished merge." -msgstr "" +msgstr "Beende wegen nicht abgeschlossenem Merge." #: archive.c:12 msgid "git archive [] [...]" msgstr "git archive [] [...]" #: archive.c:13 @@ -1084,25 +1083,25 @@ msgstr "" #: builtin/merge.c:983 #, c-format msgid "Could not open '%s' for writing" msgstr "Konnte '%s' nicht zum Schreiben öffnen." #: refs.c:3001 -#, fuzzy, c-format +#, c-format msgid "could not delete reference %s: %s" -msgstr "Konnte %s nicht entfernen" +msgstr "Konnte Referenz %s nicht entfernen: %s" #: refs.c:3004 -#, fuzzy, c-format +#, c-format msgid "could not delete references: %s" -msgstr "Konnte %s nicht entfernen" +msgstr "Konnte Referenzen nicht entfernen: %s" #: refs.c:3013 -#, fuzzy, c-format +#, c-format msgid "could not remove reference %s" -msgstr "Konnte Branch %s nicht löschen" +msgstr "Konnte Referenz %s nicht löschen" #: ref-filter.c:660 msgid "unable to parse format" msgstr "Konnte Format nicht parsen." #: remote.c:792 @@ -1228,20 +1227,19 @@ msgstr[1] "" msgid " (use \"git pull\" to merge the remote branch into yours)\n" msgstr "" " (benutzen Sie \"git pull\", um Ihren Branch mit dem Remote-Branch " "zusammenzuführen)\n" #: revision.c:2198 -#, fuzzy msgid "your current branch appears to be broken" -msgstr "Sie sind auf einem Branch, der noch geboren wird" +msgstr "Ihr aktueller Branch scheint fehlerhaft zu sein." #: revision.c:2201 -#, fuzzy, c-format +#, c-format msgid "your current branch '%s' does not have any commits yet" -msgstr "Branch '%s' zeigt auf keinen Commit" +msgstr "Ihr aktueller Branch '%s' hat noch keine Commits." #: revision.c:2395 msgid "--first-parent is incompatible with --bisect" msgstr "Die Optionen --first-parent und --bisect sind inkompatibel." #: run-command.c:83 @@ -1260,18 +1258,18 @@ msgstr "Fehler beim Signieren des \"push\"-Zertifikates" #: send-pack.c:404 msgid "the receiving end does not support --signed push" msgstr "" "die Gegenseite unterstützt keinen signierten Versand (\"--signed push\")" #: send-pack.c:406 -#, fuzzy msgid "" "not sending a push certificate since the receiving end does not support --" "signed push" msgstr "" -"die Gegenseite unterstützt keinen signierten Versand (\"--signed push\")" +"kein Versand des \"push\"-Zertifikates, da die Gegenseite keinen signierten\n" +"Versand (\"--signed push\") unterstützt" #: send-pack.c:418 msgid "the receiving end does not support --atomic push" msgstr "die Gegenseite unterstützt keinen atomaren Versand (\"--atomic push\")" #: sequencer.c:183 @@ -1311,13 +1309,13 @@ msgstr "" msgid "Your local changes would be overwritten by revert." msgstr "Ihre lokalen Änderungen würden von \"revert\" überschrieben werden." #: sequencer.c:222 msgid "Commit your changes or stash them to proceed." msgstr "" -"Tragen Sie Ihre Änderungen ein oder benutzen Sie \"stash\", um fortzufahren." +"Committen Sie Ihre Änderungen oder benutzen Sie \"stash\", um fortzufahren." #. TRANSLATORS: %s will be "revert" or "cherry-pick" #: sequencer.c:309 #, c-format msgid "%s: Unable to write new index file" msgstr "%s: Konnte neue Index-Datei nicht schreiben" @@ -1594,15 +1592,15 @@ msgstr "Konnte Eingabe-Datei '%s' nicht lesen" #: trailer.c:704 msgid "could not read from stdin" msgstr "konnte nicht von der Standard-Eingabe lesen" #: transport-helper.c:1025 -#, fuzzy, c-format +#, c-format msgid "Could not read ref %s" -msgstr "Konnte %s nicht lesen." +msgstr "Konnte Referenz %s nicht lesen." #: unpack-trees.c:203 msgid "Checking out files" msgstr "Checke Dateien aus" #: urlmatch.c:120 @@ -1632,18 +1630,18 @@ msgstr "ungültige Portnummer" #: urlmatch.c:322 msgid "invalid '..' path segment" msgstr "ungültiges '..' Pfadsegment" #: wrapper.c:219 wrapper.c:362 -#, fuzzy, c-format +#, c-format msgid "could not open '%s' for reading and writing" -msgstr "Konnte '%s' nicht zum Lesen öffnen." +msgstr "Konnte '%s' nicht zum Lesen und Schreiben öffnen." #: wrapper.c:221 wrapper.c:364 -#, fuzzy, c-format +#, c-format msgid "could not open '%s' for writing" msgstr "Konnte '%
Re: [PATCH 2/2] fetch: fetch submodules in parallel
On Mon, Sep 14, 2015 at 09:46:58AM -0700, Stefan Beller wrote: > I tried implementing a buffering solution for both stdout and stderr, > but that doesn't really workout well if you consider interleaved output > on the pipes as we cannot accurately replay that later on. To do that > we would need to store the timing information of the channels, at least > the relative order of it like: > > (stdout, First comes text to stdout), > (stderr, interrupted by text in stderr) > (stdout, but stdout doesn't bother, blasting more text) > (stderr, continues to interrupt) > > obtaining the information is inherently racy, as all we can do is > polling/reading from both stdout/err as fast as possible but without > proper synchronization mechanisms we cannot be sure. I don't think you need exact timing information. This is no different than running the commands themselves, with stdout and stderr writing to a pty that your terminal emulator will then read() from. If the program produces intermingled stdout/stderr that clogs up the terminal, that is its problem. The only difference is that we're going to save it and later replay it all very quickly. So I think it would be sufficient just to retain the original order. > I will add documentation explaining why the async output case > will only deal with one channel. I chose stderr as that's already > available and needed in this use case. I suspect you could just set child->stdout_to_stderr in this case, and then you get your ordering for free. But probably in the general case people would want to run inspection commands that produce a useful stdout. To handle multiple channels, I think you could just do a linked list of buffers rather than a single strbuf. Like: struct io_chunk { int channel; char *buf; size_t len; struct io_chunk *next; }; and just keep appending chunks to the list (and to dump them, just walk the list, writing each to the appropriate channel descriptor). -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: [PATCH] l10n: de.po: translate 123 new messages
Hi, thanks for review! Good eyes. :-) 2015-09-13 20:37 GMT+02:00 Matthias Rüster : > Hi Ralf, > > thanks for your work! > I have only a few things to add: > > > one little typo: > >> @@ -1228,20 +1227,19 @@ msgstr[1] "" >> msgid " (use \"git pull\" to merge the remote branch into yours)\n" >> msgstr "" >> " (benutzen Sie \"git pull\", um Ihren Branch mit dem Remote-Branch " >> "zusammenzuführen)\n" >> >> #: revision.c:2198 >> -#, fuzzy >> msgid "your current branch appears to be broken" >> -msgstr "Sie sind auf einem Branch, der noch geboren wird" >> +msgstr "Ihr aktuell Branch scheint fehlerhaft zu sein." >> >> #: revision.c:2201 >> -#, fuzzy, c-format >> +#, c-format >> msgid "your current branch '%s' does not have any commits yet" >> -msgstr "Branch '%s' zeigt auf keinen Commit" >> +msgstr "Ihr aktueller Branch '%s' hat noch keine Commits." >> >> #: revision.c:2395 >> msgid "--first-parent is incompatible with --bisect" >> msgstr "Die Optionen --first-parent und --bisect sind inkompatibel." >> >> #: run-command.c:83 > > > > Should be: "Ihr aktueller Branch scheint fehlerhaft zu sein." > > And here: > >> @@ -1896,44 +1894,41 @@ msgstr " (benutzen Sie \"git am --skip\", um >> diesen Patch auszulassen)" >> msgid " (use \"git am --abort\" to restore the original branch)" >> msgstr "" >> " (benutzen Sie \"git am --abort\", um den ursprünglichen Branch " >> "wiederherzustellen)" >> >> #: wt-status.c:1105 >> -#, fuzzy >> msgid "No commands done." >> -msgstr "Keine Commits geparst." >> +msgstr "Keine Kommandos ausgeführt." >> >> #: wt-status.c:1108 >> #, c-format >> msgid "Last command done (%d command done):" >> msgid_plural "Last commands done (%d commands done):" >> -msgstr[0] "" >> -msgstr[1] "" >> +msgstr[0] "Letztes Kommando ausgeführt (%d Kommandos ausgeführt):" >> +msgstr[1] "Letzte Kommandos ausgeführt (%d Kommandos ausgeführt):" >> >> #: wt-status.c:1119 >> #, c-format > > > in the first version the singular "command" is used: > [0] ... (%d Kommando ausgeführt): > > > Should be the same here: > >> #: wt-status.c:1127 >> #, c-format >> msgid "Next command to do (%d remaining command):" >> msgid_plural "Next commands to do (%d remaining commands):" >> -msgstr[0] "" >> -msgstr[1] "" >> +msgstr[0] "Nächstes auszuführendes Kommando (%d Kommandos verbleibend):" >> +msgstr[1] "Nächste auszuführende Kommandos (%d Kommandos verbleibend):" >> > > [0] ... (%d Kommando verbleibend) > > > Maybe leave the apostrophes in this message since it is not in the english > version (?): > >> @@ -2504,15 +2494,15 @@ msgstr "auf leere Historie anwenden" >> #: builtin/am.c:1684 builtin/commit.c:1752 builtin/merge.c:829 >> #: builtin/merge.c:854 >> msgid "failed to write commit object" >> msgstr "Fehler beim Schreiben des Commit-Objektes." >> >> #: builtin/am.c:1716 builtin/am.c:1720 >> -#, fuzzy, c-format >> +#, c-format >> msgid "cannot resume: %s does not exist." >> -msgstr "Branch '%s' existiert nicht" >> +msgstr "Kann nicht fortsetzen: '%s' existiert nicht" >> >> #: builtin/am.c:1736 >> msgid "cannot be interactive without stdin connected to a terminal." >> msgstr "" >> "Kann nicht interaktiv sein, ohne dass die Standard-Eingabe mit einem " >> "Terminal verbunden ist." > > > "Kann nicht fortsetzen: %s existiert nicht" > > > This: > >> >> #: builtin/am.c:2194 >> -#, fuzzy >> msgid "git am [options] [(|)...]" >> -msgstr "git merge [] [...]" >> +msgstr "git am [Optionen] [(|)...]" >> >> #: builtin/am.c:2195 >> -#, fuzzy >> msgid "git am [options] (--continue | --skip | --abort)" >> -msgstr "versuchen Sie \"git cherry-pick (--continue | --quit | >> --abort)\"" >> +msgstr "git am [Optionen] (--continue | --quit | --abort)" >> > > > should be: > "git am [Optionen] (--continue | --skip | --abort)" > > (--skip instead of --quit) > > > > One little typo here: > >> @@ -9289,19 +9270,18 @@ msgstr "Die Option --delete ist inkompatibel mit >> --all, --mirror und --tags." >> >> #: builtin/push.c:581 >> msgid "--delete doesn't make sense without any refs" >> msgstr "Die Option --delete kann nur mit Referenzen verwendet werden." >> >> #: builtin/read-tree.c:37 >> -#, fuzzy >> msgid "" >> "git read-tree [(-m [--trivial] [--aggressive] | --reset | >> --prefix=) " >> "[-u [--exclude-per-directory=] | -i]] [--no-sparse-checkout] >> [--" >> "index-output=] (--empty | [ >> []])" >> msgstr "" >> -"git read-tree [[-m [--trivial] [--aggressive] | --reset | >> --prefix=] " >> +"git read-tree [([-m [--trivial] [--aggressive] | --reset | >> --prefix=) " >> "[-u [--exclude-per-directory=] | -i]] [--no-sparse-checkout] >> [--" >> "index-output=] (--empty | [ >> " >> "[]])" >> >> #: builtin/read-tree.c:110 >> msgid "write resulting index to " > > > > [([-m [--trivial] should be [(-m [--trivial] > > >> @@ -11246,16 +11226,15 @@ msgstr "mit anderen zusammenarbeiten (siehe >> auch: git help workflows)" >> >> #: common-cmds.h:17 >>
Re: [PATCH v2 2/2] dir.c: don't exclude whole dir prematurely if neg pattern may match
Nguyễn Thái Ngọc Duy writes: > diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt > index 473623d..889a72a 100644 > --- a/Documentation/gitignore.txt > +++ b/Documentation/gitignore.txt > @@ -82,12 +82,9 @@ PATTERN FORMAT > > - An optional prefix "`!`" which negates the pattern; any > matching file excluded by a previous pattern will become > + included again. It is possible to re-include a file if a parent > + directory of that file is excluded, with restrictions. See section > + NOTES for detail. Sounds like a very useful thing. > - If the pattern ends with a slash, it is removed for the > purpose of the following description, but it would only find > @@ -141,6 +138,18 @@ not tracked by Git remain untracked. > To stop tracking a file that is currently tracked, use > 'git rm --cached'. > > +To re-include a file when its parent directory is excluded, the > +following conditions must be met: > + > + - The directory part in the re-include rules must be literal (i.e. no > + wildcards) > + > + - The rules to exclude the parent directory must not end with a > + trailing slash. > + > + - The rules to exclude the parent directory must have at least one > + slash. > + In this bulletted list, don't the readers also need to be told that having "/abc" in .gitignore (but not "!/abc/anything" in .gitignore) and "!foo" in abc/.gitignore would not cause us to descend into "/abc" just to examine "abc/.gitignore" with pessimistic assumption that there might be some exclusion in there? > diff --git a/t/t3001-ls-files-others-exclude.sh > b/t/t3001-ls-files-others-exclude.sh > index 3fc484e..9de49a6 100755 > --- a/t/t3001-ls-files-others-exclude.sh > +++ b/t/t3001-ls-files-others-exclude.sh > @@ -305,4 +305,24 @@ test_expect_success 'ls-files with "**" patterns and no > slashes' ' > test_cmp expect actual > ' > > +test_expect_success 'negative patterns' ' > + git init reinclude && > + ( > + cd reinclude && > + cat >.gitignore <<-\EOF && > + /foo > + !foo/bar/bar > + EOF > + mkdir -p foo/bar && > + touch abc foo/def foo/bar/ghi foo/bar/bar && > + git ls-files -o --exclude-standard >../actual && > + cat >../expected <<-\EOF && > + .gitignore > + abc > + foo/bar/bar > + EOF > + test_cmp ../expected ../actual > + ) > +' And another test here may want to explicitly ensure that we are not overly pessimising the ignore processing, so that later changes will not break it, I think. Or do we already have such a case covered by an existing test? Thanks. -- 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 v7] git-p4: add config git-p4.pathEncoding
From: Lars Schneider diff to v6: * Always print the encoded path in verbose mode. v6 is already on next (a9e383). This patch must be applied on next. Is this the right way to handle this situation? Thanks, Lars Lars Schneider (1): git-p4: improve path encoding verbose output git-p4.py | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) -- 2.5.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 v7] git-p4: improve path encoding verbose output
From: Lars Schneider If a path with non-ASCII characters is detected then print always the encoding and the encoded string in verbose mode. Signed-off-by: Lars Schneider --- git-p4.py | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/git-p4.py b/git-p4.py index d45cf2b..da25d3f 100755 --- a/git-p4.py +++ b/git-p4.py @@ -2220,16 +2220,15 @@ class P4Sync(Command, P4UserMap): text = regexp.sub(r'$\1$', text) contents = [ text ] -if gitConfig("git-p4.pathEncoding"): -relPath = relPath.decode(gitConfig("git-p4.pathEncoding")).encode('utf8', 'replace') -elif self.verbose: -try: -relPath.decode('ascii') -except: -print ( -"Path with Non-ASCII characters detected and no path encoding defined. " -"Please check the encoding: %s" % relPath -) +try: +relPath.decode('ascii') +except: +encoding = 'utf8' +if gitConfig('git-p4.pathEncoding'): +encoding = gitConfig('git-p4.pathEncoding') +relPath = relPath.decode(encoding).encode('utf8', 'replace') +if self.verbose: +print 'Path with non-ASCII characters detected. Used %s to encode: %s ' % (encoding, relPath) self.gitStream.write("M %s inline %s\n" % (git_mode, relPath)) -- 2.5.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
Re: [PATCH] l10n: de.po: translate 123 new messages
Hi, thanks for review! Am 13. September 2015 um 20:35 schrieb Phillip Sz : >> #: wt-status.c:1105 >> -#, fuzzy >> msgid "No commands done." >> -msgstr "Keine Commits geparst." >> +msgstr "Keine Kommandos ausgeführt." >> > > Are you sure about this? "done" could also mean something like "erledigt". > I considered using "erledigt" but came to the conclusion that "ausgeführt" (english: executed) is more suitable for saying that a command is done. -- 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] doc: show usage of branch description
"Philip Oakley" writes: > It still means that my patch is incomplete in its aim to bring out > these possible broader usages. > > I haven't yet looked at the mail archives to see if there is more > around the time of those introductions. I guess this is largely my fault, but I think "git grep" is an easier source of truth to work with than the list archive. It eventually boils down to branch.*.description configuration and all users of that would call read_branch_desc(), so if you check callers of that helper function and see which commit introduced that call for what purpose ("blame" is your friend), you would know how they use the information under what condition. $ git grep -n read_branch_desc -- \*.c branch.c:143:int read_branch_desc(struct strbuf *buf, const char *branch_name) builtin/branch.c:771: read_branch_desc(&buf, branch_name); builtin/fmt-merge-msg.c:211:if (!read_branch_desc(&desc, name)) { builtin/log.c:888: read_branch_desc(&desc, branch_name); $ git blame -L210,212 -s builtin/fmt-merge-msg.c 898eacd8 210) 898eacd8 211) if (!read_branch_desc(&desc, name)) { 898eacd8 212) const char *bp = desc.buf; $ git show -s 898eacd8 commit 898eacd8ada2d012f977948350ed60845e238037 Author: Junio C Hamano Date: Thu Oct 6 23:12:09 2011 -0700 fmt-merge-msg: use branch.$name.description This teaches "merge --log" and fmt-merge-msg to use branch description information when merging a local topic branch into the mainline. The description goes between the branch name label and the list of commit titles. The refactoring to share the common configuration parsing between merge and fmt-merge-msg needs to be made into a separate patch. Signed-off-by: Junio C Hamano etc. etc. -- 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 2/2] git-p4: handle "Translation of file content failed"
From: Lars Schneider A P4 repository can get into a state where it contains a file with type UTF-16 that does not contain a valid UTF-16 BOM. If git-p4 attempts to retrieve the file then the process crashes with a "Translation of file content failed" error. Fix this by detecting this error and retrieving the file as binary instead. The result in Git is the same. Known issue: This works only if git-p4 is executed in verbose mode. In normal mode no exceptions are thrown and git-p4 just exits. Signed-off-by: Lars Schneider --- git-p4.py | 27 --- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/git-p4.py b/git-p4.py index 073f87b..5ae25a6 100755 --- a/git-p4.py +++ b/git-p4.py @@ -134,13 +134,11 @@ def read_pipe(c, ignore_error=False): sys.stderr.write('Reading pipe: %s\n' % str(c)) expand = isinstance(c,basestring) -p = subprocess.Popen(c, stdout=subprocess.PIPE, shell=expand) -pipe = p.stdout -val = pipe.read() -if p.wait() and not ignore_error: -die('Command failed: %s' % str(c)) - -return val +p = subprocess.Popen(c, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=expand) +(out, err) = p.communicate() +if p.returncode != 0 and not ignore_error: +die('Command failed: %s\nError: %s' % (str(c), err)) +return out def p4_read_pipe(c, ignore_error=False): real_cmd = p4_build_cmd(c) @@ -2186,10 +2184,17 @@ class P4Sync(Command, P4UserMap): # them back too. This is not needed to the cygwin windows version, # just the native "NT" type. # -text = p4_read_pipe(['print', '-q', '-o', '-', "%s@%s" % (file['depotFile'], file['change']) ]) -if p4_version_string().find("/NT") >= 0: -text = text.replace("\r\n", "\n") -contents = [ text ] +try: +text = p4_read_pipe(['print', '-q', '-o', '-', '%s@%s' % (file['depotFile'], file['change'])]) +except Exception as e: +if 'Translation of file content failed' in str(e): +type_base = 'binary' +else: +raise e +else: +if p4_version_string().find('/NT') >= 0: +text = text.replace('\r\n', '\n') +contents = [ text ] if type_base == "apple": # Apple filetype files will be streamed as a concatenation of -- 2.5.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 v2 0/2] git-p4: handle "Translation of file content failed"
From: Lars Schneider diff to v1: * add a test case * use Popen "communication" function instead of "wait" Thanks to Junio for feedback! Known issue: My fix works only if git-p4 is executed in verbose mode. In normal mode no exceptions are thrown and git-p4 just exits. Lars Schneider (2): git-p4: add test case for "Translation of file content failed" error git-p4: handle "Translation of file content failed" git-p4.py | 27 ++--- t/t9824-git-p4-handle-utf16-without-bom.sh | 47 ++ 2 files changed, 63 insertions(+), 11 deletions(-) create mode 100755 t/t9824-git-p4-handle-utf16-without-bom.sh -- 2.5.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 v2 1/2] git-p4: add test case for "Translation of file content failed" error
From: Lars Schneider A P4 repository can get into a state where it contains a file with type UTF-16 that does not contain a valid UTF-16 BOM. If git-p4 attempts to retrieve the file then the process crashes with a "Translation of file content failed" error. Signed-off-by: Lars Schneider --- t/t9824-git-p4-handle-utf16-without-bom.sh | 47 ++ 1 file changed, 47 insertions(+) create mode 100755 t/t9824-git-p4-handle-utf16-without-bom.sh diff --git a/t/t9824-git-p4-handle-utf16-without-bom.sh b/t/t9824-git-p4-handle-utf16-without-bom.sh new file mode 100755 index 000..fa8043b --- /dev/null +++ b/t/t9824-git-p4-handle-utf16-without-bom.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +test_description='git p4 handle UTF-16 without BOM' + +. ./lib-git-p4.sh + +UTF16="\\x97\\x0\\x97\\x0" + +test_expect_success 'start p4d' ' + start_p4d +' + +test_expect_success 'init depot with UTF-16 encoded file and artificially remove BOM' ' + ( + cd "$cli" && + echo "file1 -text" > .gitattributes && + perl -e "printf \"$UTF16\"" >file1 && + p4 add -t utf16 file1 && + + p4 add .gitattributes && + p4 submit -d "file1" + ) && + + ( + cd "db" && + p4d -jc && + # P4D automatically adds a BOM. Remove it here to make the file invalid. + perl -i -ne "print unless eof" depot/file1,v && + perl -e "printf \"@$UTF16@\"" >> depot/file1,v && + p4d -jrF checkpoint.1 + ) +' + +test_expect_success 'clone depot with invalid UTF-16 file' ' + git p4 clone --dest="$git" --verbose //depot && + ( + cd "$git" && + perl -e "printf \"$UTF16\"" > expect && + test_cmp_bin expect file1 + ) +' + +test_expect_success 'kill p4d' ' + kill_p4d +' + +test_done -- 2.5.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
Re: [PATCH] Pass amend to pre-commit hook
On 14/09/15 15:47, Jeff King wrote: On Mon, Sep 14, 2015 at 01:14:20PM +0100, Alan Clucas wrote: Pass a single parameter 'amend' to the pre-commit hook when performing a commit amend. I think this is a sensible thing to want, and it has come up a few times. I'm not sure why the last round didn't get merged, though. Looks like it just slipped through the cracks. Here are the relevant threads: http://thread.gmane.org/gmane.comp.version-control.git/260122 http://thread.gmane.org/gmane.comp.version-control.git/260245 Looks like there was some question of what to pass in the normal, non-amend case. I've added interested parties from the original thread to the cc here. -Peff Ah thanks. My google-fu didn't find any of those threads, I should have tried specifically searching the archives I guess. Maybe with a little cajoling we could get some version of this passed. The issue that came up before was my worry, I didn't like defining the interface that way in case it needed extending... (but other hooks also have bad interfaces, so wasn't sure what precedent to follow). Alan -- 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 2/2] fetch: fetch submodules in parallel
On Sat, Sep 12, 2015 at 12:11 PM, Junio C Hamano wrote: >> + if (start_command(&children[i])) >> + die(_("Could not start child process")); >> + flags = fcntl(children[i].err, F_GETFL); >> + fcntl(children[i].err, F_SETFL, flags | O_NONBLOCK); > > This function in run-command.c looks as if it is a generic helper to > be called by anybody, but it seems to only care about the standard > error and not the standard output stream, which means potential > users that do not dup them together cannot use it. Is that a big > downside, or is it sufficient to document the API to say that > children must do so? I offhand do not think the latter is > unreasonable, but that may be only because I haven't thought things > through. Yes it ought to become a generic helper eventually. I tried implementing a buffering solution for both stdout and stderr, but that doesn't really workout well if you consider interleaved output on the pipes as we cannot accurately replay that later on. To do that we would need to store the timing information of the channels, at least the relative order of it like: (stdout, First comes text to stdout), (stderr, interrupted by text in stderr) (stdout, but stdout doesn't bother, blasting more text) (stderr, continues to interrupt) obtaining the information is inherently racy, as all we can do is polling/reading from both stdout/err as fast as possible but without proper synchronization mechanisms we cannot be sure. I will add documentation explaining why the async output case will only deal with one channel. I chose stderr as that's already available and needed in this use case. > >> + nr_processes++; >> + slots[i] = 1; >> + } >> + >> + /* prepare data for select call */ >> + FD_ZERO(&fdset); >> + maxfd = 0; >> + for (i = 0; i < n; i++) { >> + if (!slots[i]) >> + continue; >> + FD_SET(children[i].err, &fdset); >> + if (children[i].err > maxfd) >> + maxfd = children[i].err; >> + } >> + timeout.tv_sec = 0; >> + timeout.tv_usec = 50; >> + >> + i = select(maxfd + 1, &fdset, NULL, NULL, &timeout); > > I thought we try to use poll() and on systems with only select we > allow compat/ to emulate in our code. I did not know that. I'll rewrite the patch to use poll instead. > >> + if (i < 0) { >> + if (errno == EINTR) >> + /* A signal was caught; try again */ >> + continue; >> + else if (errno == ENOMEM) >> + die_errno("BUG: keeping track of fds is hard"); >> + else if (errno == EINVAL) >> + die_errno("BUG: invalid arguments to select"); >> + else if (errno == EBADF) >> + die_errno("BUG: keeping track of fds is hard"); >> + else >> + die_errno("Unknown error with select"); > > I doubt that the later part of elseif cascade adds any value. You > will see errno printed anyway. ok. -- 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: Unable to create temporary file '/var/git/tmv3-target-overlay.git/shallow_Un8ZOR': Permission denied
On Mon, 2015-08-31 at 16:56 +0700, Duy Nguyen wrote: > On Fri, Aug 21, 2015 at 6:36 PM, Joakim Tjernlund > wrote: > > I cannot push: > > # > git push origin > > Login for jo...@git.transmode.se > > Password: > > Counting objects: 7, done. > > Delta compression using up to 4 threads. > > Compressing objects: 100% (7/7), done. > > Writing objects: 100% (7/7), 13.73 KiB | 0 bytes/s, done. > > Total 7 (delta 4), reused 0 (delta 0) > > fatal: Unable to create temporary file > > '/var/git/tmv3-target-overlay.git/shallow_Un8ZOR': Permission > > denied > > fatal: The remote end hung up unexpectedly > > fatal: The remote end hung up unexpectedly > > Noted. Will try to fix (but probably not fast). At first I thought > this was an old bug, but that old bug [1] is in the fetch/clone path, > not push. Not sure if the same approach can be reused here (i.e.avoid > temp files altoghether). > > [1] b790e0f (upload-pack: send shallow info over stdin to pack-objects > - 2014-03-11) Noticed I had forgotten to reply ... An even simpler fix would be to have an tmp dir within the repo, aka: /var/git/tmv3-target-overlay.git/tmp/shallow_Un8ZOR This would cover all cases when one must create a tmp file Jocke-- 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 3/8] branch: roll show_detached HEAD into regular ref_list
Karthik Nayak writes: > On Mon, Sep 14, 2015 at 12:01 AM, Eric Sunshine > wrote: >> Specifically, I think you're referring to [1] (?). >> >> [1]: >> http://thread.gmane.org/gmane.comp.version-control.git/276363/focus=276676 > > No not that, that is handled in the previous patch series. > > I can't find the reference either, but the comment was along the lines of what > Matthieu just mentioned above, I had another message in mind too. Never mind, the comment is addressed, we don't need to know if it was a real message or a collective hallucination ;-). -- 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] Pass amend to pre-commit hook
On Mon, Sep 14, 2015 at 01:14:20PM +0100, Alan Clucas wrote: > Pass a single parameter 'amend' to the pre-commit hook when performing a > commit amend. I think this is a sensible thing to want, and it has come up a few times. I'm not sure why the last round didn't get merged, though. Looks like it just slipped through the cracks. Here are the relevant threads: http://thread.gmane.org/gmane.comp.version-control.git/260122 http://thread.gmane.org/gmane.comp.version-control.git/260245 Looks like there was some question of what to pass in the normal, non-amend case. I've added interested parties from the original thread to the cc here. -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: [PATCH v4 3/8] branch: roll show_detached HEAD into regular ref_list
On Mon, Sep 14, 2015 at 12:01 AM, Eric Sunshine wrote: > On Sun, Sep 13, 2015 at 12:46 PM, Eric Sunshine > wrote: >> On Sun, Sep 13, 2015 at 8:12 AM, Matthieu Moy >> wrote: >>> Karthik Nayak writes: >>> @@ -679,15 +682,20 @@ static int print_ref_list(int kinds, int detached, int verbose, int abbrev, stru if (verbose) maxwidth = calc_maxwidth(&ref_list, strlen(remote_prefix)); - qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp); + index = ref_list.index; + + /* Print detached HEAD before sorting and printing the rest */ + if (detached && (ref_list.list[index - 1].kind == REF_DETACHED_HEAD) && + !strcmp(ref_list.list[index - 1].name, head)) { + print_ref_item(&ref_list.list[index - 1], maxwidth, verbose, abbrev, +1, remote_prefix); + index -= 1; + } >>> >>> I think Eric already mentionned it, but I don't remember the conclusion >>> and can't find it in the archives. Wouldn't it be cleaner to actually >>> remove the detached head from the array (do "ref_list.index -= 1" >>> instead of "index -= 1", and possibly free() what needs to be freed? >> >> I think Michael Haggerty mentioned something along those lines... > > Specifically, I think you're referring to [1] (?). > > [1]: > http://thread.gmane.org/gmane.comp.version-control.git/276363/focus=276676 No not that, that is handled in the previous patch series. I can't find the reference either, but the comment was along the lines of what Matthieu just mentioned above, But like I replied on [Patch 6/8] Its taken care of in that particular patch. Here it doesn't seem to be needed. -- Regards, Karthik Nayak -- 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] doc: show usage of branch description
The branch description will be included in 'git format-patch --cover-letter' and in 'git pull-request' emails. It can also be used in the automatic merge message. Tell the reader. While here, clarify that the description may be a multi-line explanation of the purpose of the branch's patch series. Signed-off-by: Philip Oakley --- fc0aa39 (Documentation: include 'merge.branchdesc' for merge and config as well, 2015-05-27) recently added details of the low level config flag. Changes since V1: discovered that git merge can also include the branch description if enabled, so added a minimal mention to flag it to the reader. --- Documentation/git-branch.txt | 4 +++- Documentation/git-format-patch.txt | 2 +- Documentation/git-merge.txt| 2 +- Documentation/git-request-pull.txt | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt index a67138a..bbbade4 100644 --- a/Documentation/git-branch.txt +++ b/Documentation/git-branch.txt @@ -197,7 +197,9 @@ start-point is either a local or remote-tracking branch. --edit-description:: Open an editor and edit the text to explain what the branch is - for, to be used by various other commands (e.g. `request-pull`). + for, to be used by various other commands (e.g. `format-patch`, + `request-pull`, and `merge` (if enabled)). Multi-line explanations + may be used. --contains []:: Only list branches which contain the specified commit (HEAD diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index 0dac4e9..4035649 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -213,7 +213,7 @@ feeding the result to `git send-email`. --[no-]cover-letter:: In addition to the patches, generate a cover letter file - containing the shortlog and the overall diffstat. You can + containing the branch description, shortlog and the overall diffstat. You can fill in a description in the file before sending it out. --notes[=]:: diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt index 273a100..a62d672 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@ -78,7 +78,7 @@ will be appended to the specified message. + The 'git fmt-merge-msg' command can be used to give a good default for automated 'git merge' -invocations. +invocations. The automated message can include the branch description. --[no-]rerere-autoupdate:: Allow the rerere mechanism to update the index with the diff --git a/Documentation/git-request-pull.txt b/Documentation/git-request-pull.txt index 283577b..c32cb0b 100644 --- a/Documentation/git-request-pull.txt +++ b/Documentation/git-request-pull.txt @@ -14,7 +14,8 @@ DESCRIPTION --- Generate a request asking your upstream project to pull changes into -their tree. The request, printed to the standard output, summarizes +their tree. The request, printed to the standard output, +begins with the branch description, summarizes the changes and indicates from where they can be pulled. The upstream project is expected to have the commit named by -- 2.4.2.windows.1.5.gd32afb6 -- 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 v5 1/7] git-p4: add optional type specifier to gitConfig reader
From: Lars Schneider The functions “gitConfig” and “gitConfigBool” are almost identical. Make “gitConfig” more generic by adding an optional type specifier. Use the type specifier “—bool” with “gitConfig” to implement “gitConfigBool. This prepares the implementation of other type specifiers such as “—int”. Signed-off-by: Lars Schneider --- git-p4.py | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/git-p4.py b/git-p4.py index 073f87b..c139cab 100755 --- a/git-p4.py +++ b/git-p4.py @@ -604,9 +604,12 @@ def gitBranchExists(branch): _gitConfig = {} -def gitConfig(key): +def gitConfig(key, typeSpecifier=None): if not _gitConfig.has_key(key): -cmd = [ "git", "config", key ] +cmd = [ "git", "config" ] +if typeSpecifier: +cmd += [ typeSpecifier ] +cmd += [ key ] s = read_pipe(cmd, ignore_error=True) _gitConfig[key] = s.strip() return _gitConfig[key] @@ -617,10 +620,7 @@ def gitConfigBool(key): in the config.""" if not _gitConfig.has_key(key): -cmd = [ "git", "config", "--bool", key ] -s = read_pipe(cmd, ignore_error=True) -v = s.strip() -_gitConfig[key] = v == "true" +_gitConfig[key] = gitConfig(key, '--bool') == "true" return _gitConfig[key] def gitConfigList(key): -- 2.5.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 v5 3/7] git-p4: return an empty list if a list config has no values
From: Lars Schneider Signed-off-by: Lars Schneider --- git-p4.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/git-p4.py b/git-p4.py index 40ad4ae..90d3b90 100755 --- a/git-p4.py +++ b/git-p4.py @@ -638,6 +638,8 @@ def gitConfigList(key): if not _gitConfig.has_key(key): s = read_pipe(["git", "config", "--get-all", key], ignore_error=True) _gitConfig[key] = s.strip().split(os.linesep) +if _gitConfig[key] == ['']: +_gitConfig[key] = [] return _gitConfig[key] def p4BranchesInGit(branchesAreInRemotes=True): -- 2.5.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 v5 7/7] git-p4: add Git LFS backend for large file system
From: Lars Schneider Add example implementation including test cases for the large file system using Git LFS. Pushing files to the Git LFS server is not tested. Signed-off-by: Lars Schneider --- git-p4.py | 72 t/t9824-git-p4-git-lfs.sh | 288 ++ 2 files changed, 360 insertions(+) create mode 100755 t/t9824-git-p4-git-lfs.sh diff --git a/git-p4.py b/git-p4.py index bfe71b5..1f2ee97 100755 --- a/git-p4.py +++ b/git-p4.py @@ -1039,6 +1039,78 @@ class MockLFS(LargeFileSystem): os.makedirs(remotePath) shutil.copyfile(localLargeFile, os.path.join(remotePath, os.path.basename(localLargeFile))) +class GitLFS(LargeFileSystem): +"""Git LFS as backend for the git-p4 large file system. + See https://git-lfs.github.com/ for details.""" + +def __init__(self, *args): +LargeFileSystem.__init__(self, *args) +self.baseGitAttributes = [] + +def generatePointer(self, cloneDestination, contentFile): +"""Generate a Git LFS pointer for the content. Return LFS Pointer file + mode and content which is stored in the Git repository instead of + the actual content. Return also the new location of the actual + content. + """ +pointerProcess = subprocess.Popen( +['git', 'lfs', 'pointer', '--file=' + contentFile], +stdout=subprocess.PIPE +) +pointerFile = pointerProcess.stdout.read() +if pointerProcess.wait(): +os.remove(contentFile) +die('git-lfs pointer command failed. Did you install the extension?') +pointerContents = [i+'\n' for i in pointerFile.split('\n')[2:][:-1]] +oid = pointerContents[1].split(' ')[1].split(':')[1][:-1] +localLargeFile = os.path.join( +cloneDestination, +'.git', 'lfs', 'objects', oid[:2], oid[2:4], +oid, +) +# LFS Spec states that pointer files should not have the executable bit set. +gitMode = '100644' +return (gitMode, pointerContents, localLargeFile) + +def pushFile(self, localLargeFile): +uploadProcess = subprocess.Popen( +['git', 'lfs', 'push', '--object-id', 'origin', os.path.basename(localLargeFile)] +) +if uploadProcess.wait(): +die('git-lfs push command failed. Did you define a remote?') + +def generateGitAttributes(self): +return ( +self.baseGitAttributes + +[ +'\n', +'#\n', +'# Git LFS (see https://git-lfs.github.com/)\n', +'#\n', +] + +['*.' + f.replace(' ', '[:space:]') + ' filter=lfs -text\n' +for f in sorted(gitConfigList('git-p4.largeFileExtensions')) +] + +['/' + f.replace(' ', '[:space:]') + ' filter=lfs -text\n' +for f in sorted(self.largeFiles) if not self.hasLargeFileExtension(f) +] +) + +def addLargeFile(self, relPath): +LargeFileSystem.addLargeFile(self, relPath) +self.writeToGitStream('100644', '.gitattributes', self.generateGitAttributes()) + +def removeLargeFile(self, relPath): +LargeFileSystem.removeLargeFile(self, relPath) +self.writeToGitStream('100644', '.gitattributes', self.generateGitAttributes()) + +def processContent(self, cloneDestination, git_mode, relPath, contents): +if relPath == '.gitattributes': +self.baseGitAttributes = contents +return (git_mode, self.generateGitAttributes()) +else: +return LargeFileSystem.processContent(self, cloneDestination, git_mode, relPath, contents) + class Command: def __init__(self): self.usage = "usage: %prog [options]" diff --git a/t/t9824-git-p4-git-lfs.sh b/t/t9824-git-p4-git-lfs.sh new file mode 100755 index 000..bf34efa --- /dev/null +++ b/t/t9824-git-p4-git-lfs.sh @@ -0,0 +1,288 @@ +#!/bin/sh + +test_description='Clone repositories and store files in Git LFS' + +. ./lib-git-p4.sh + +git lfs help >/dev/null 2>&1 || { + skip_all='skipping git p4 Git LFS tests; Git LFS not found' + test_done +} + +test_file_in_lfs () { + FILE="$1" + SIZE="$2" + EXPECTED_CONTENT="$3" + cat "$FILE" | grep "size $SIZE" + HASH=$(cat "$FILE" | grep "oid sha256:" | sed -e 's/oid sha256://g') + LFS_FILE=".git/lfs/objects/${HASH:0:2}/${HASH:2:2}/$HASH" + echo $EXPECTED_CONTENT >expect + test_path_is_file "$FILE" && + test_path_is_file "$LFS_FILE" && + test_cmp expect "$LFS_FILE" +} + +test_file_count_in_dir () { + DIR="$1" + EXPECTED_COUNT="$2" + find "$DIR" -type f >actual + test_line_count = $EXPECTED_COUNT actual +} + +test_expect_success 'start p4d' ' + start_p4d +' + +test_expect_success 'Create repo with binary files' ' + client
[PATCH v5 6/7] git-p4: add support for large file systems
From: Lars Schneider Perforce repositories can contain large (binary) files. Migrating these repositories to Git generates very large local clones. External storage systems such as Git LFS [1], Git Fat [2], Git Media [3], git-annex [4] try to address this problem. Add a generic mechanism to detect large files based on extension, uncompressed size, and/or compressed size. [1] https://git-lfs.github.com/ [2] https://github.com/jedbrown/git-fat [3] https://github.com/alebedev/git-media [4] https://git-annex.branchable.com/ Signed-off-by: Lars Schneider --- Documentation/git-p4.txt | 32 +++ git-p4.py | 139 + t/t9823-git-p4-mock-lfs.sh | 96 +++ 3 files changed, 257 insertions(+), 10 deletions(-) create mode 100755 t/t9823-git-p4-mock-lfs.sh diff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt index 82aa5d6..3f21e95 100644 --- a/Documentation/git-p4.txt +++ b/Documentation/git-p4.txt @@ -510,6 +510,38 @@ git-p4.useClientSpec:: option '--use-client-spec'. See the "CLIENT SPEC" section above. This variable is a boolean, not the name of a p4 client. +git-p4.largeFileSystem:: + Specify the system that is used for large (binary) files. Please note + that large file systems do not support the 'git p4 submit' command. + Only Git LFS [1] is implemented right now. Download + and install the Git LFS command line extension to use this option + and configure it like this: ++ +- +git config git-p4.largeFileSystem GitLFS +- ++ + [1] https://git-lfs.github.com/ + +git-p4.largeFileExtensions:: + All files matching a file extension in the list will be processed + by the large file system. Do not prefix the extensions with '.'. + +git-p4.largeFileThreshold:: + All files with an uncompressed size exceeding the threshold will be + processed by the large file system. By default the threshold is + defined in bytes. Add the suffix k, m, or g to change the unit. + +git-p4.largeFileCompressedThreshold:: + All files with a compressed size exceeding the threshold will be + processed by the large file system. This option might slow down + your clone/sync process. By default the threshold is defined in + bytes. Add the suffix k, m, or g to change the unit. + +git-p4.pushLargeFiles:: + Boolean variable which defines if large files are automatically + pushed to a server. + Submit variables git-p4.detectRenames:: diff --git a/git-p4.py b/git-p4.py index b465356..bfe71b5 100755 --- a/git-p4.py +++ b/git-p4.py @@ -22,6 +22,8 @@ import platform import re import shutil import stat +import zipfile +import zlib try: from subprocess import CalledProcessError @@ -932,6 +934,111 @@ def wildcard_present(path): m = re.search("[*#@%]", path) return m is not None +class LargeFileSystem(object): +"""Base class for large file system support.""" + +def __init__(self, writeToGitStream): +self.largeFiles = set() +self.writeToGitStream = writeToGitStream + +def generatePointer(self, cloneDestination, contentFile): +"""Return the content of a pointer file that is stored in Git instead of + the actual content.""" +assert False, "Method 'generatePointer' required in " + self.__class__.__name__ + +def pushFile(self, localLargeFile): +"""Push the actual content which is not stored in the Git repository to + a server.""" +assert False, "Method 'pushFile' required in " + self.__class__.__name__ + +def hasLargeFileExtension(self, relPath): +return reduce( +lambda a, b: a or b, +[relPath.endswith('.' + e) for e in gitConfigList('git-p4.largeFileExtensions')], +False +) + +def generateTempFile(self, contents): +contentFile = tempfile.NamedTemporaryFile(prefix='git-p4-large-file', delete=False) +for d in contents: +contentFile.write(d) +contentFile.flush() +contentFile.close() +return contentFile.name + +def exceedsLargeFileThreshold(self, relPath, contents): +if gitConfigInt('git-p4.largeFileThreshold'): +contentsSize = sum(len(d) for d in contents) +if contentsSize > gitConfigInt('git-p4.largeFileThreshold'): +return True +if gitConfigInt('git-p4.largeFileCompressedThreshold'): +contentsSize = sum(len(d) for d in contents) +if contentsSize <= gitConfigInt('git-p4.largeFileCompressedThreshold'): +return False +contentTempFile = self.generateTempFile(contents) +compressedContentFile = tempfile.NamedTemporaryFile(prefix='git-p4-large-file', delete=False) +zf = zipfile.ZipFile(compressedContentFile.name, mode='w') +zf
Re: git submodule ignores --git-dir
On 11.09.2015 17:15, Jens Lehmann wrote: > Unfortunately trying to show git the right work tree: > > $ git --git-dir=$PWD/repo2/.git --work-tree=$PWD/repo2 submodule update --init > > Didn't work as I expected it to either: > > fatal: /home/Sledge/libexec/git-core/git-submodule cannot be used without a > working tree. Yes, that's confusing. I'm not sure how other commands use the --work-tree flag and if having the git-submodule script `cd` into the work tree would be acceptable. What do you think? On 11.09.2015 17:28, John Keeping wrote: > There's also "git -C /path/to/repo" which avoids the need for a separate > "cd". > Thank you, that works! -- 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 v5 4/7] git-p4: add file streaming progress in verbose mode
From: Lars Schneider If a file is streamed from P4 to Git then the verbose mode prints continuously the progress as percentage like this: //depot/file.bin 20% (10 MB) Upon completion the progress is overwritten with depot source, local file and size like this: //depot/file.bin --> local/file.bin (10 MB) Signed-off-by: Lars Schneider --- git-p4.py | 20 ++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/git-p4.py b/git-p4.py index 90d3b90..e7a7ea4 100755 --- a/git-p4.py +++ b/git-p4.py @@ -2164,7 +2164,9 @@ class P4Sync(Command, P4UserMap): def streamOneP4File(self, file, contents): relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes) if verbose: -sys.stderr.write("%s\n" % relPath) +size = int(self.stream_file['fileSize']) +sys.stdout.write('\r%s --> %s (%i MB)\n' % (file['depotFile'], relPath, size/1024/1024)) +sys.stdout.flush() (type_base, type_mods) = split_p4_type(file["type"]) @@ -2241,7 +2243,8 @@ class P4Sync(Command, P4UserMap): def streamOneP4Deletion(self, file): relPath = self.stripRepoPath(file['path'], self.branchPrefixes) if verbose: -sys.stderr.write("delete %s\n" % relPath) +sys.stdout.write("delete %s\n" % relPath) +sys.stdout.flush() self.gitStream.write("D %s\n" % relPath) # handle another chunk of streaming data @@ -2281,10 +2284,23 @@ class P4Sync(Command, P4UserMap): # 'data' field we need to append to our array for k in marshalled.keys(): if k == 'data': +if 'streamContentSize' not in self.stream_file: +self.stream_file['streamContentSize'] = 0 +self.stream_file['streamContentSize'] += len(marshalled['data']) self.stream_contents.append(marshalled['data']) else: self.stream_file[k] = marshalled[k] +if (verbose and +'streamContentSize' in self.stream_file and +'fileSize' in self.stream_file and +'depotFile' in self.stream_file): +size = int(self.stream_file["fileSize"]) +if size > 0: +progress = 100*self.stream_file['streamContentSize']/size +sys.stdout.write('\r%s %d%% (%i MB)' % (self.stream_file['depotFile'], progress, int(size/1024/1024))) +sys.stdout.flush() + self.stream_have_file_info = True # Stream directly from "p4 files" into "git fast-import" -- 2.5.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 v5 5/7] git-p4: check free space during streaming
From: Lars Schneider git-p4 will just halt if there is not enough disk space while streaming content from P4 to Git. Add a check to ensure at least 4 times (arbitrarily chosen) the size of a streamed file is available. Signed-off-by: Lars Schneider --- git-p4.py | 27 ++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/git-p4.py b/git-p4.py index e7a7ea4..b465356 100755 --- a/git-p4.py +++ b/git-p4.py @@ -104,6 +104,16 @@ def chdir(path, is_client_path=False): path = os.getcwd() os.environ['PWD'] = path +def calcDiskFree(dirname): +"""Return free space in bytes on the disk of the given dirname.""" +if platform.system() == 'Windows': +free_bytes = ctypes.c_ulonglong(0) +ctypes.windll.kernel32.GetDiskFreeSpaceExW(ctypes.c_wchar_p(dirname), None, None, ctypes.pointer(free_bytes)) +return free_bytes.value +else: +st = os.statvfs(dirname) +return st.f_bavail * st.f_frsize + def die(msg): if verbose: raise Exception(msg) @@ -2038,6 +2048,14 @@ class P4Sync(Command, P4UserMap): self.clientSpecDirs = None self.tempBranches = [] self.tempBranchLocation = "git-p4-tmp" +self.largeFileSystem = None +self.cloneDestination = None + +if gitConfig('git-p4.largeFileSystem'): +largeFileSystemConstructor = globals()[gitConfig('git-p4.largeFileSystem')] +self.largeFileSystem = largeFileSystemConstructor( +lambda git_mode, relPath, contents: self.writeToGitStream(git_mode, relPath, contents) +) if gitConfig("git-p4.syncFromOrigin") == "false": self.syncWithOrigin = False @@ -2256,6 +2274,14 @@ class P4Sync(Command, P4UserMap): if marshalled["code"] == "error": if "data" in marshalled: err = marshalled["data"].rstrip() + +if not err and self.cloneDestination and 'fileSize' in self.stream_file: +required_bytes = int((4 * int(self.stream_file["fileSize"])) - calcDiskFree(self.cloneDestination)) +if required_bytes > 0: +err = 'Not enough space left on %s! Free at least %i MB.' % ( +os.path.abspath(self.cloneDestination), required_bytes/1024/1024 +) + if err: f = None if self.stream_have_file_info: @@ -3218,7 +3244,6 @@ class P4Clone(P4Sync): optparse.make_option("--bare", dest="cloneBare", action="store_true", default=False), ] -self.cloneDestination = None self.needsGit = False self.cloneBare = False -- 2.5.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 v5 0/7] git-p4: add support for large file systems
From: Lars Schneider Diff to v4: * Add streaming progress in verbose mode. * Add check for free disk space. * Remove the limitation that no .gitattribues must be present. * Refactor large file system classes. The base implementation does not assume a ".gitattributes mechanism" anymore. * Throw error if the large file system is used with 'git p4 submit'. Add warning in the docs, too. Thanks to Junio and Luke feedback! Lars Schneider (7): git-p4: add optional type specifier to gitConfig reader git-p4: add gitConfigInt reader git-p4: return an empty list if a list config has no values git-p4: add file streaming progress in verbose mode git-p4: check free space during streaming git-p4: add support for large file systems git-p4: add Git LFS backend for large file system Documentation/git-p4.txt | 32 + git-p4.py | 279 --- t/t9823-git-p4-mock-lfs.sh | 96 +++ t/t9824-git-p4-git-lfs.sh | 288 + 4 files changed, 678 insertions(+), 17 deletions(-) create mode 100755 t/t9823-git-p4-mock-lfs.sh create mode 100755 t/t9824-git-p4-git-lfs.sh -- 2.5.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 v5 2/7] git-p4: add gitConfigInt reader
From: Lars Schneider Add a git config reader for integer variables. Please note that the git config implementation automatically supports k, m, and g suffixes. Signed-off-by: Lars Schneider --- git-p4.py | 11 +++ 1 file changed, 11 insertions(+) diff --git a/git-p4.py b/git-p4.py index c139cab..40ad4ae 100755 --- a/git-p4.py +++ b/git-p4.py @@ -623,6 +623,17 @@ def gitConfigBool(key): _gitConfig[key] = gitConfig(key, '--bool') == "true" return _gitConfig[key] +def gitConfigInt(key): +if not _gitConfig.has_key(key): +cmd = [ "git", "config", "--int", key ] +s = read_pipe(cmd, ignore_error=True) +v = s.strip() +try: +_gitConfig[key] = int(gitConfig(key, '--int')) +except ValueError: +_gitConfig[key] = None +return _gitConfig[key] + def gitConfigList(key): if not _gitConfig.has_key(key): s = read_pipe(["git", "config", "--get-all", key], ignore_error=True) -- 2.5.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
Re: [PATCH] doc: show usage of branch description
From: "Philip Oakley" From: "Jacob Keller" Hi, On Sat, Sep 12, 2015 at 3:51 PM, Philip Oakley wrote: The branch description will be included in 'git format-patch --cover-letter' and in 'git pull-request' emails. Tell the reader. [...] Are these the only locations? Just want to make sure while we're updating it. A bit more delving found http://stackoverflow.com/a/8858853/717355 which suggests `git merge` would use it, but with no mention in the `git merge --help` man page. A link to the `git fmt-merge-msg` ("for internal use by scripts") finally provides the extra: merge.branchdesc In addition to branch names, populate the log message with the branch description text associated with them. Defaults to false. However, that config key isn't listed in `git config --help` man page, so that capability is a bit buried. (note the default!) This is incorrect. It was fixed in fc0aa39 (Documentation: include 'merge.branchdesc' for merge and config as well, 2015-05-27), but my local docs hadn't included it. It still means that my patch is incomplete in its aim to bring out these possible broader usages. i.e. mentioning 'merge' as a command that uses the branch description, and noting it within the merge pages. -- 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] Pass amend to pre-commit hook
Pass a single parameter 'amend' to the pre-commit hook when performing a commit amend. This allows 'incremental improvement' pre-commit hooks to prevent new code from violating a rule, but also allow the pre-commit hook to pass an amended commit where the amend has reverted back to the original code (which may not pass that same rule). Example: I have a new whitespace rule. Old code violates this rule and will not be fixed up for blame reasons. My pre-commit hook detects _new_ lines which violate the rule and rejects them, however, my original commit passes. I amend the code to revert back to the original code (which violates the rule). Without this change I cannot detect this is an amend and reject the change (unless --no-verify). With this I can detect this is an amend and verify the patch as a whole is not in violation of the rule. Signed-off-by: Alan Clucas --- Hello, This is my first submission to git, so hopefully I've managed to get the formatting right. This patch should be explained above, and would also help out the folks at overcommit who have this (pretty horrid) solution to the same issue: https://github.com/brigade/overcommit/issues/146 https://github.com/brigade/overcommit/pull/167 Thanks, Alan Clucas Documentation/githooks.txt | 10 ++ builtin/commit.c | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index 7ba0ac9..49d7adb 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -73,10 +73,12 @@ pre-commit ~~ This hook is invoked by 'git commit', and can be bypassed -with `--no-verify` option. It takes no parameter, and is -invoked before obtaining the proposed commit log message and -making a commit. Exiting with non-zero status from this script -causes the 'git commit' to abort. +with `--no-verify` option. It takes zero or one parameters. +If a parameter is given it will be 'amend' indicating this is +a commit amend (if an `--amend` option was given). It is invoked +before obtaining the proposed commit log message and making a +commit. Exiting with non-zero status from this script causes the +'git commit' to abort. The default 'pre-commit' hook, when enabled, catches introduction of lines with trailing whitespaces and aborts the commit when diff --git a/builtin/commit.c b/builtin/commit.c index 63772d0..936a614 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -671,7 +671,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, /* This checks and barfs if author is badly specified */ determine_author_info(author_ident); - if (!no_verify && run_commit_hook(use_editor, index_file, "pre-commit", NULL)) + if (!no_verify && run_commit_hook(use_editor, index_file, "pre-commit", amend?"amend":NULL, NULL)) return 0; if (squash_message) { -- 2.4.1.168.g1ea28e1 -- 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 v7 1/3] worktree: add top-level worktree.c
On Sat, Sep 12, 2015 at 10:39 PM, Eric Sunshine wrote: > I realize that this is modeled closely after existing code in > branch.c, but, with the exception of parsing the ref file and > constructing a worktree structure, the main worktree case (id == NULL) > is entirely disjoint from the linked worktree case (id != NULL). This > suggests strongly that get_worktree() should be split into two > functions, one for the main worktree and one for linked worktrees, > which would make the code easier to understand. You might call the > functions get_main_worktree() and get_linked_worktree(id) (or perhaps > drop "linked" from the latter name). I originally wrote it like that, but I felt that the code looked like it was mostly duplicated in the functions. I can give it a relook. >> + >> +struct worktree_list *get_worktree_list() > > Can we be more concise and call this get_worktrees()? > I prefer 'get_worktree_list' because I also added the 'get_worktree' function, and I wanted to differentiate the function names. >> diff --git a/worktree.h b/worktree.h >> new file mode 100644 >> index 000..2bc0ab8 >> --- /dev/null >> +++ b/worktree.h >> @@ -0,0 +1,48 @@ >> +#ifndef WORKTREE_H >> +#define WORKTREE_H >> + >> +struct worktree { >> + char *path; >> + char *git_dir; >> + char *head_ref; >> + unsigned char head_sha1[20]; >> + int is_detached; >> + int is_bare; >> +}; >> + >> +struct worktree_list { >> + struct worktree *worktree; >> + struct worktree_list *next; >> +}; > > I don't care too strongly, but an alternate approach (which I probably > would have taken) would be to have get_worktrees() simply return an > array of 'struct worktree' objects, hence no need for the additional > 'struct worktree_list'. The slight complication with this approach, > though, is that get_worktrees() either also needs to return the length > of the array, or the array should end with some sort of end-of-array > sentinel. An obvious sentinel would be path==NULL or git_dir==NULL or > all of the above. > > Client iteration is just about the same with the array approach as > with the linked-list approach. > I can't see what benefit this would provide. I would sooner change the returned list into an array-backed list struct. Alternatively, I think adding a list_head pointer to this structure could benefit client code. -- 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] doc: show usage of branch description
From: "Jacob Keller" Hi, On Sat, Sep 12, 2015 at 3:51 PM, Philip Oakley wrote: The branch description will be included in 'git format-patch --cover-letter' and in 'git pull-request' emails. Tell the reader. While here, clarify that the description may be a multi-line explanation of the purpose of the branch's patch series. Signed-off-by: Philip Oakley --- This is a short doc patch to follow up $gmane/277628 where Johannes Schindelin noted this otherwise undocumented feature. Thanks for this. Documentation/git-branch.txt | 3 ++- Documentation/git-format-patch.txt | 2 +- Documentation/git-request-pull.txt | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt index a67138a..79ad1c7 100644 --- a/Documentation/git-branch.txt +++ b/Documentation/git-branch.txt @@ -197,7 +197,8 @@ start-point is either a local or remote-tracking branch. --edit-description:: Open an editor and edit the text to explain what the branch is - for, to be used by various other commands (e.g. `request-pull`). + for, to be used by various other commands (e.g. `format-patch` + and `request-pull`). Multi-line explanations may be used. Are these the only locations? Just want to make sure while we're updating it. Searching for 'description' has many hits so it's not easy to be really sure. I had thought I'd asked an SO question ($SO/q/6866838) about branch descriptions many years ago, whose answers indicated it was little used, but actually I'd asked about the repo description (doh) which AFAICT is only used by gitweb. A bit more delving found http://stackoverflow.com/a/8858853/717355 which suggests `git merge` would use it, but with no mention in the `git merge --help` man page. A link to the `git fmt-merge-msg` ("for internal use by scripts") finally provides the extra: merge.branchdesc In addition to branch names, populate the log message with the branch description text associated with them. Defaults to false. However, that config key isn't listed in `git config --help` man page, so that capability is a bit buried. (note the default!) It still means that my patch is incomplete in its aim to bring out these possible broader usages. I haven't yet looked at the mail archives to see if there is more around the time of those introductions. Otherwise, for what it's worth... Acked-by: Jacob Keller For the future, it would also be nice to allow some use within `git branch` for a `--show[-full]-description` option such that when branch info is being given (-a, -l, etc), then the descriptions for the local branches (which may have descriptions) are displayed, either as a single first line, or as a full multi-line description. But that's coding & review for the future. -- 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 2/5] enter_repo: avoid duplicating logic, use is_git_directory() instead
On Sun, Sep 13, 2015 at 8:04 AM, Junio C Hamano wrote: > Duy Nguyen writes: > >> On Mon, Sep 7, 2015 at 11:33 PM, Junio C Hamano wrote: >>> Nguyễn Thái Ngọc Duy writes: >>> Signed-off-by: Nguyễn Thái Ngọc Duy --- >>> >>> The cover letter talks about "local clone", and in this entire >>> series, I saw new tests only for the local case, but doesn't this >>> and the next change also affect the case where a Git daemon or a >>> upload-pack process is serving the remote repository? >>> >>> And if so, how is that case affected? >> >> People who serve .git-dir repos should not be affected (I think we >> have enough test cases covering that). People can serve .git-file >> repos as well, which is sort of tested in the local clone test case >> because upload-pack is involved for providing remote refs, I think. > > Unfortunately, the above is still not unclear to me. > > Was serving from a linked repository working without these five > patches, i.e. was the local case the only one that was broken and > needed fixing with these five patches? If so, the log message > should mention that (i.e. "remote case was working OK but local was > broken because ...; change this and that to make local one work as > well"). If the remote case also was broken and fixed by these five > patches, then that is also worth mentioning the same way. > > I didn't ask you to explain it to me in the first place in a > response. The review comment pointed out that the proposed log > message was unclear and those who will be reading "git log" output > need clearer description. I know. I sent the re-roll before receiving this. I think I still haven't mentioned the impact on remote case. Another update coming, maybe next weekend. -- 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: Fwd: Translate Pro Git book to Russian and Ukrainian
On Mon, 14 Sep 2015 12:48:52 +0300 Konstantin Khomoutov wrote: > > Good day! > > I am Russian and Ukrainian native speaker. I have a little free time > > and I want to help in translating. > > What I may do for it? > > Please read [1] -- especially the section titled "Contributing" there. > > 1. https://github.com/progit/progit2 Well, so basically [2] has a list of in-progress translations with the links to their respective Git repos hosted on Github. So I'd just get in touch with their respective maintainers -- may be through opening an issue of commenting on existing ones. 2. https://progit.org/translations -- 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: Fwd: Translate Pro Git book to Russian and Ukrainian
On Sat, 12 Sep 2015 23:11:40 +0300 Dmitry Strelnikov wrote: > Good day! > I am Russian and Ukrainian native speaker. I have a little free time > and I want to help in translating. > What I may do for it? Please read [1] -- especially the section titled "Contributing" there. 1. https://github.com/progit/progit2 -- 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 Deployment using existing multiple environments
On Sun, Sep 13, 2015 at 10:55 PM, Sukhwinder Singh wrote: > Thank you for the reply. Let's say I do setup three different repositories > then how can we move work from one repository to the other. For example, from > Test Environment to UAT. If there are any links that you can provide me that > I can check, it'll be great. > > Regards, > Sukhwinder Singh > Generally speaking there are two ways of moving work from one repository to another. The first is the "pull" where you request data from a remote repository and then merge that data into your own. This is what you're doing when you perform a clone, a fetch, or a pull. It's what everyone does all the time when working with a local copy of a "trusted" remote repository. It can also be done between two "trusted" remotes, if your workflow is more distributed. (ie: more than one "official" source). The second form of moving work is the "push" where you upload your work into another repository. This is most commonly used when the workflow is "centralized". By that I mean there is a single authoritative repository. Or when you are moving your own work on a local machine into a remotely accessible machine for others to pull from. As Johannes said above, you really need to determine the work flow and team style you want before you can really understand the best way to setup repositories. For example, if you setup using a distributed chain of command, you can have one person be the "maintainer" of each given trusted repository. Then, maintainers can pull (or equivalent-ly, pull-request) between each other. This is generally how a project would work when using github. One person is the maintainer, then a developer "forks" the project, makes some changes, then requests that the maintainer pull these changes. The maintainer has final say and will perform the final merge in cases of conflict. In addition, maintainer is the one who says "this is ok to go into this repository". You can also instead opt to use a single centralized repository. Thus, developers would work on code and get it ready to submit, and then simply perform a push. If the push requires a merge git will tell the user to update. There are many tools such as server side hooks in order to enforce various behaviors. This flow generally doesn't use sole maintainers, as each developer has access to push directly. It may work well for smaller teams or for dedicated teams who don't change developers often. A lot comes down to how your team is structured. Do you have one person who's job can be to maintain the repository? Do you have several developers who don't want to be the sole owner? Is your team willing to function much more distributed? In the end, it's generally always a good idea to designate at least one repository as the "authority" so that everyone knows where to look for release tags and other such data. Myself, I would say that I prefer to use the pull-request model so that code gets more review, as "push" based models tend not to do review. (Exception: Gerrit, but this uses "git push" on the command line to do something very much not like a push) Regards, Jake -- 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