summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* rerere: remove an null statementjc/rerere-multiJunio C Hamano2016-05-191-1/+1
| | | | | | | J6t spotted that previous commit added an empty statement by mistake. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: plug memory leaks upon "rerere forget" failureJunio C Hamano2016-05-111-8/+17
| | | | Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: adjust 'forget' to multi-variant world orderJunio C Hamano2016-04-062-1/+37
| | | | | | | | | | | | | | | | | | | | | | | Because conflicts with the same contents inside conflict blocks enclosed by "<<<<<<<" and ">>>>>>>" can now have multiple variants to help three-way merge to adjust to the differences outside the conflict blocks, "rerere forget $path" needs to be taught that there may be multiple recorded resolutions that share the same conflict hash (which groups the conflicts with "the same contents inside conflict blocks"), among which there are some that would not be relevant to the conflict we are looking at. These "other variants" that happen to share the same conflict hash should not be cleared, and the variant that would apply to the current conflict may not be the zero-th one (which is the only one that is cleared by the current code). After finding the conflict hash, iterate over the existing variants and try to resolve the conflict using each of them to find the one that "cleanly" resolves the current conflict. That is the one we want to forget and record the preimage for, so that the user can record the corrected resolution. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: split code to call ll_merge() furtherJunio C Hamano2016-04-061-16/+31
| | | | | | | | | | | | | | | | | | The merge() helper function is given an existing rerere ID (i.e. the name of the .git/rr-cache/* subdirectory, and the variant number) that identifies one <preimage, postimage> pair, try to see if the conflicted state in the given path can be resolved by using the pair, and if this succeeds, then update the conflicted path with the result in the working tree. To implement rerere_forget() in the multiple variant world, we'd need a helper to do the "see if a <preimage, postimage> pair cleanly resolves a conflicted state we have in-core" part, without actually touching any file in the working tree, in order to identify which variant(s) to remove. Split the logic to do so into a separate helper function try_merge() out of merge(). Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: move code related to "forget" togetherJunio C Hamano2016-04-061-97/+97
| | | | | | | | | "rerere forget" is the only user of handle_cache() helper, which in turn is the only user of rerere_io that reads from an in-core buffer whose getline method is implemented as rerere_mem_getline(). Gather them together. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: gc and clearJunio C Hamano2016-04-062-45/+123
| | | | | | | | Adjust "git rerere gc" and "git rerere clear" to the new world order with rerere database with multiple variants for the same shape of conflicts. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: do use multiple variantsJunio C Hamano2016-03-152-39/+61
| | | | | | | | | | | | | | 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 <gitster@pobox.com>
* t4200: rerere a merge with two identical conflictsJunio C Hamano2016-03-151-0/+74
| | | | | | | | | | | 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 <gitster@pobox.com>
* rerere: allow multiple variants to existJunio C Hamano2016-03-152-22/+106
| | | | | | | | | | | | | | | | | 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 <gitster@pobox.com>
* rerere: delay the recording of preimageJunio C Hamano2016-03-151-27/+25
| | | | | | | | | | | | | | | | | | | | | | | 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 <preimage,postimage> 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 remove a stale postimage, which most likely is totally unrelated to the resolution of this new conflict, when we create a new preimage under $ID when $GIT_DIR/rr-cache/$ID already exists. In later patches, we will further update this logic to be "do we have <preimage,postimage> 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 <gitster@pobox.com>
* rerere: handle leftover rr-cache/$ID directory and postimage filesJunio C Hamano2016-03-152-18/+41
| | | | | | | | | | | | | | | | | | | 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 <gitster@pobox.com>
* rerere: scan $GIT_DIR/rr-cache/$ID when instantiating a rerere_idJunio C Hamano2016-02-081-3/+29
| | | | | | | | 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 <gitster@pobox.com>
* rerere: split conflict ID furtherJunio C Hamano2016-02-082-6/+58
| | | | | | | | | | | | | | | | | | | | | | 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 <preimage,postimage> 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 <gitster@pobox.com>
* rerere: replace strcpy with xsnprintfjk/rerere-xsnprintfJeff King2016-02-081-2/+2
| | | | | | | | | | This shouldn't overflow, as we are copying a sha1 hex into a 41-byte buffer. But it does not hurt to use a bound-checking function, which protects us and makes auditing for overflows easier. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: un-nest merge() furtherjc/rerereJunio C Hamano2015-07-241-24/+26
| | | | | | | By consistently using "upon failure, set 'ret' and jump to out" pattern, flatten the function further. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: use "struct rerere_id" instead of "char *" for conflict IDJunio C Hamano2015-07-243-28/+85
| | | | | | | | | | | | This gives a thin abstraction between the conflict ID that is a hash value obtained by inspecting the conflicts and the name of the directory under $GIT_DIR/rr-cache/, in which the previous resolution is recorded to be replayed. The plan is to make sure that the presence of the directory does not imply the presense of a previous resolution and vice-versa, and later allow us to have more than one pair of <preimage, postimage> for a given conflict ID. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: call conflict-ids IDsJunio C Hamano2015-07-243-41/+41
| | | | | | | Most places we call conflict IDs "name" and some others we call them "hex"; update all of them to "id". Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: further clarify do_rerere_one_path()Junio C Hamano2015-07-241-9/+6
| | | | Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: further de-dent do_plain_rerere()Junio C Hamano2015-07-241-32/+33
| | | | | | It's just easier to follow this way. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: refactor "replay" part of do_plain_rerere()Junio C Hamano2015-07-241-35/+40
| | | | | | | | | Extract the body of a loop that attempts to replay recorded resolution for each conflicted path into a helper function, not because I want to call it from multiple places later, but because the logic has become too deeply nested and hard to read. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: explain the remainderJunio C Hamano2015-07-241-0/+20
| | | | | | | | | | | Explain the internals of rerere as in-code comments, while sprinkling "NEEDSWORK" comment to highlight iffy bits and questionable assumptions. This covers the codepath that implements "rerere gc" and "rerere clear". Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: explain "rerere forget" codepathJunio C Hamano2015-07-241-0/+24
| | | | | | | | | | Explain the internals of rerere as in-code comments, while sprinkling "NEEDSWORK" comment to highlight iffy bits and questionable assumptions. This covers the codepath that implements "rerere forget". Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: explain the primary codepathJunio C Hamano2015-07-241-13/+82
| | | | | | | | | | | Explain the internals of rerere as in-code comments, while sprinkling "NEEDSWORK" comment to highlight iffy bits and questionable assumptions. This one covers the codepath reached from rerere(), the primary interface to the subsystem. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: explain MERGE_RR management helpersJunio C Hamano2015-07-241-0/+41
| | | | | | | | | | | | Explain the internals of rerere as in-code comments, while sprinkling "NEEDSWORK" comment to highlight iffy bits and questionable assumptions. This one covers the "$GIT_DIR/MERGE_RR" file and in-core merge_rr that are used to keep track of the status of "rerere" session in progress. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: fix benign off-by-one non-bug and clarify codeJunio C Hamano2015-07-241-1/+8
| | | | | | | | | | | | | | | | | | | | | | | | | rerere_io_putconflict() wants to use a limited fixed-sized buf[] on stack repeatedly to formulate a longer string, but its implementation is doubly confusing: * When it knows that the whole thing fits in buf[], it wants to fill early part of buf[] with conflict marker characters, followed by a LF and a NUL. It miscounts the size of the buffer by 1 and does not use the last byte of buf[]. * When it needs to show only the early part of a long conflict marker string (because the whole thing does not fit in buf[]), it adjusts the number of bytes shown in the current round in a strange-looking way. It makes sure that this round does not emit all bytes and leaves at least one byte to the next round, so that "it all fits" case will pick up the rest and show the terminating LF. While this is correct, one needs to stop and think for a while to realize why it is correct without an explanation. Fix the benign off-by-one, and add comments to explain the strange-looking size adjustment. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: explain the rerere I/O abstractionJunio C Hamano2015-07-241-7/+31
| | | | | | | | | Explain the internals of rerere as in-code comments. This one covers our thin I/O abstraction to read from either a file or a memory while optionally writing out to a file. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: do not leak mmfile[] for a path with multiple stage #1 entriesJunio C Hamano2015-07-241-2/+4
| | | | | | | | | | | | | | | | | | A conflicted index can have multiple stage #1 entries when dealing with a criss-cross merge and using the "resolve" merge strategy. Plug the leak by reading only the first one of the same stage entries. Strictly speaking, this fix does change the semantics, in that we used to use the last stage #1 entry as the common ancestor when doing the plain-vanilla three-way merge, but with the leak fix, we will use the first stage #1 entry. But it is not a grave backward compatibility breakage. Either way, we are arbitrarily picking one of multiple stage #1 entries and using it, ignoring others, and there is no meaning in the ordering of these stage #1 entries. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: stop looping unnecessarilyJunio C Hamano2015-07-241-10/+7
| | | | | | | | | | | | handle_cache() loops 3 times starting from an index entry that is unmerged, while ignoring an entry for a path that is different from what we are looking for. As the index is sorted, once we see a different path, we know we saw all stages for the path we are interested in. Just loop while we see the same path and then break, instead of continuing for 3 times. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: drop want_sp parameter from is_cmarker()Junio C Hamano2015-07-241-5/+22
| | | | | | | | As the nature of the conflict marker line determines if there should be a SP and label after it, the caller shouldn't have to pass the parameter redundantly. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: report autoupdated paths only after actually updating themJunio C Hamano2015-07-241-10/+12
| | | | Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: write out each record of MERGE_RR in one goJunio C Hamano2015-07-241-7/+9
| | | | | | | | | | | | | Instead of writing the hash for a conflict, a HT, and the path with three separate write_in_full() calls, format them into a single record into a strbuf and write it out in one go. As a more recent "rerere remaining" codepath abuses the .util field of the merge_rr data to store a sentinel token, make sure that codepath does not call into this function (of course, "remaining" is a read-only operation and currently does not call it). Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: lift PATH_MAX limitationJunio C Hamano2015-07-241-20/+15
| | | | | | | | | | | | | | | | | | The MERGE_RR file records a collection of NUL-terminated entries, each of which consists of - a hash that identifies the conflict - a HT - the pathname We used to read this piece-by-piece, and worse yet, read the pathname part a byte at a time into a fixed buffer of size PATH_MAX. Instead, read a whole entry using strbuf_getwholeline() and parse out the fields. This way, we issue fewer read(2) calls and more importantly we do not have to limit the pathname to PATH_MAX. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: plug conflict ID leaksJunio C Hamano2015-07-241-2/+5
| | | | | | | | | | | | | | The merge_rr string list stores the conflict ID (a hexadecimal string that is used to index into $GIT_DIR/rr-cache) in the .util field of its elements, and when do_plain_rerere() resolves a conflict, the field is cleared. Also, when rerere_forget() recomputes the conflict ID to updates the preimage file, the conflict ID for the path is updated. We forgot to free the existing conflict ID when we did these two operations. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: handle conflicts with multiple stage #1 entriesJunio C Hamano2015-07-241-1/+1
| | | | | | | A conflicted index can have multiple stage #1 entries when dealing with a criss-cross merge and using the "resolve" merge strategy. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* rerere: fix an off-by-one non-bugJunio C Hamano2015-06-281-4/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | When ac49f5ca (rerere "remaining", 2011-02-16) split out a new helper function check_one_conflict() out of find_conflict() function, so that the latter will use the returned value from the new helper to update the loop control variable that is an index into active_cache[], the new variable incremented the index by one too many when it found a path with only stage #1 entry at the very end of active_cache[]. This "strange" return value does not have any effect on the loop control of two callers of this function, as they all notice that active_nr+2 is larger than active_nr just like active_nr+1 is, but nevertheless it puzzles the readers when they are trying to figure out what the function is trying to do. In fact, there is no need to do an early return. The code that follows after skipping the stage #1 entry is fully prepared to handle a case where the entry is at the very end of active_cache[]. Help future readers from unnecessary confusion by dropping an early return. We skip the stage #1 entry, and if there are stage #2 and stage #3 entries for the same path, we diagnose the path as THREE_STAGED (otherwise we say PUNTED), and then we skip all entries for the same path. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* Git 2.3.8v2.3.8Junio C Hamano2015-05-114-3/+26
| | | | Signed-off-by: Junio C Hamano <gitster@pobox.com>
* Merge branch 'mm/usage-log-l-can-take-regex' into maint-2.3Junio C Hamano2015-05-116-15/+16
|\ | | | | | | | | | | | | | | Documentation fix. * mm/usage-log-l-can-take-regex: log -L: improve error message on malformed argument Documentation: change -L:<regex> to -L:<funcname>
| * log -L: improve error message on malformed argumentmm/usage-log-l-can-take-regexMatthieu Moy2015-04-202-5/+5
| | | | | | | | | | | | | | | | | | | | | | The old message did not mention the :regex:file form. To avoid overly long lines, split the message into two lines (in case item->string is long, it will be the only part truncated in a narrow terminal). Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * Documentation: change -L:<regex> to -L:<funcname>Matthieu Moy2015-04-204-10/+11
| | | | | | | | | | | | | | | | | | | | The old wording was somehow implying that <start> and <end> were not regular expressions. Also, the common case is to use a plain function name here so <funcname> makes sense (the fact that it is a regular expression is documented in line-range-format.txt). Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Merge branch 'jc/diff-no-index-d-f' into maint-2.3Junio C Hamano2015-05-112-2/+98
|\ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The usual "git diff" when seeing a file turning into a directory showed a patchset to remove the file and create all files in the directory, but "git diff --no-index" simply refused to work. Also, when asked to compare a file and a directory, imitate POSIX "diff" and compare the file with the file with the same name in the directory, instead of refusing to run. * jc/diff-no-index-d-f: diff-no-index: align D/F handling with that of normal Git diff-no-index: DWIM "diff D F" into "diff D/F F"
| * | diff-no-index: align D/F handling with that of normal Gitjc/diff-no-index-d-fJunio C Hamano2015-03-262-2/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a commit changes a path P that used to be a file to a directory and creates a new path P/X in it, "git show" would say that file P was removed and file P/X was created for such a commit. However, if we compare two directories, D1 and D2, where D1 has a file D1/P in it and D2 has a directory D2/P under which there is a file D2/P/X, and ask "git diff --no-index D1 D2" to show their differences, we simply get a refusal "file/directory conflict". Surely, that may be what GNU diff does, but we can do better and it is easy to do so. Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * | diff-no-index: DWIM "diff D F" into "diff D/F F"Junio C Hamano2015-03-252-0/+65
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | "git diff --no-index" was supposed to be a poor-man's approach to allow using Git diff goodies outside of a Git repository, without having to patch mainstream diff implementations. Unlike a POSIX diff that treats "diff D F" (or "diff F D") as a request to compare D/F and F (or F and D/F) when D is a directory and F is a file, however, we did not accept such a command line and instead barfed with "file/directory conflict". Imitate what POSIX diff does and append the basename of the file after the name of the directory before comparing. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | Merge branch 'oh/fix-config-default-user-name-section' into maint-2.3Junio C Hamano2015-05-111-2/+2
|\ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The default $HOME/.gitconfig file created upon "git config --global" that edits it had incorrectly spelled user.name and user.email entries in it. * oh/fix-config-default-user-name-section: config: fix settings in default_user_config template
| * | | config: fix settings in default_user_config templateoh/fix-config-default-user-name-sectionOssi Herrala2015-04-171-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The name (not user) and email setting should be in config section "user" and not in "core" as documented in Documentation/config.txt. Signed-off-by: Ossi Herrala <oherrala@gmail.com> Reviewed-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | | Merge branch 'jc/epochtime-wo-tz' into maint-2.3Junio C Hamano2015-05-111-5/+9
|\ \ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | "git commit --date=now" or anything that relies on approxidate lost the daylight-saving-time offset. * jc/epochtime-wo-tz: parse_date_basic(): let the system handle DST conversion parse_date_basic(): return early when given a bogus timestamp
| * | | | parse_date_basic(): let the system handle DST conversionjc/epochtime-wo-tzJunio C Hamano2015-04-151-2/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The function parses the input to compute the broken-down time in "struct tm", and the GMT timezone offset. If the timezone offset does not exist in the input, the broken-down time is turned into the number of seconds since epoch both in the current timezone and in GMT and the offset is computed as their difference. However, we forgot to make sure tm.tm_isdst is set to -1 (i.e. let the system figure out if DST is in effect in the current timezone when turning the broken-down time to the number of seconds since epoch); it is done so at the beginning of the function, but a call to match_digit() in the function can lead to a call to gmtime_r() to clobber the field. Reported-by: Linus Torvalds <torvalds@linux-foundation.org> Diagnosed-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * | | | parse_date_basic(): return early when given a bogus timestampJunio C Hamano2015-04-151-3/+3
| | |/ / | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When the input does not have GMT timezone offset, the code computes it by computing the local and GMT time for the given timestamp. But there is no point doing so if the given timestamp is known to be a bogus one. Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | | Git 2.3.7v2.3.7Junio C Hamano2015-04-274-3/+25
| | | | | | | | | | | | | | | | Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | | Merge branch 'tb/connect-ipv6-parse-fix' into maintJunio C Hamano2015-04-273-16/+24
|\ \ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | An earlier update to the parser that disects a URL broke an address, followed by a colon, followed by an empty string (instead of the port number), e.g. ssh://example.com:/path/to/repo. * tb/connect-ipv6-parse-fix: connect.c: ignore extra colon after hostname
| * | | | connect.c: ignore extra colon after hostnametb/connect-ipv6-parse-fixTorsten Bögershausen2015-04-083-16/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Ignore an extra ':' at the end of the hostname in URL's like "ssh://example.com:/path/to/repo" The colon is meant to separate a port number from the hostname. If the port is empty, the colon should be ignored, see RFC 3986. It had been working for URLs with ssh:// scheme, but was unintentionally broken in 86ceb3, "allow ssh://user@[2001:db8::1]/repo.git" Reported-by: Reid Woodbury Jr. <reidw@rawsound.com> Signed-off-by: Torsten Bögershausen <tboegi@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>