Browse Source

Merge "get_remote_url(): also honor url.*.pushInsteadOf"

Jenkins 3 years ago
parent
commit
bde9e28e72
2 changed files with 50 additions and 23 deletions
  1. 43
    23
      git_review/cmd.py
  2. 7
    0
      git_review/tests/test_git_review.py

+ 43
- 23
git_review/cmd.py View File

@@ -64,6 +64,7 @@ _has_color = None
64 64
 _use_color = None
65 65
 _orig_head = None
66 66
 _rewrites = None
67
+_rewrites_push = None
67 68
 
68 69
 
69 70
 class colors:
@@ -409,59 +410,78 @@ def add_remote(scheme, hostname, port, project, remote):
409 410
 
410 411
 
411 412
 def populate_rewrites():
412
-    """Populate the global _rewrites map based on the output of "git-config".
413
+    """Populate the global _rewrites and _rewrites_push maps based on the
414
+    output of "git-config".
413 415
     """
414 416
 
415 417
     cmd = ['git', 'config', '--list']
416 418
     out = run_command_exc(CommandFailed, *cmd).strip()
417 419
 
418
-    global _rewrites
420
+    global _rewrites, _rewrites_push
419 421
     _rewrites = {}
422
+    _rewrites_push = {}
420 423
 
421 424
     for entry in out.splitlines():
422 425
         key, _, value = entry.partition('=')
423 426
         key = key.lower()
424 427
 
425 428
         if key.startswith('url.') and key.endswith('.insteadof'):
426
-            rewrite = key[4:-10]
429
+            rewrite = key[len('url.'):-len('.insteadof')]
427 430
             if rewrite:
428 431
                 _rewrites[value] = rewrite
432
+        elif key.startswith('url.') and key.endswith('.pushinsteadof'):
433
+            rewrite = key[len('url.'):-len('.pushinsteadof')]
434
+            if rewrite:
435
+                _rewrites_push[value] = rewrite
429 436
 
430 437
 
431
-def alias_url(url):
438
+def alias_url(url, rewrite_push):
432 439
     """Expand a remote URL. Use the global map _rewrites to replace the
433
-    longest match with its equivalent.
440
+    longest match with its equivalent. If rewrite_push is True, try
441
+    _rewrites_push before _rewrites.
434 442
     """
435 443
 
436 444
     if _rewrites is None:
437 445
         populate_rewrites()
438 446
 
439
-    longest = None
440
-    for alias in _rewrites:
441
-        if (url.startswith(alias)
442
-                and (longest is None or len(longest) < len(alias))):
443
-            longest = alias
447
+    if rewrite_push:
448
+        maps = [_rewrites_push, _rewrites]
449
+    else:
450
+        maps = [_rewrites]
451
+
452
+    for rewrites in maps:
453
+        # If Git finds a pushInsteadOf alias, it uses that even if
454
+        # there is a longer insteadOf alias.
455
+        longest = None
456
+        for alias in rewrites:
457
+            if (url.startswith(alias)
458
+                    and (longest is None or len(longest) < len(alias))):
459
+                longest = alias
460
+
461
+        if longest:
462
+            return url.replace(longest, rewrites[longest])
444 463
 
445
-    if longest:
446
-        url = url.replace(longest, _rewrites[longest])
447 464
     return url
448 465
 
449 466
 
450 467
 def get_remote_url(remote):
451 468
     """Retrieve the remote URL. Read the configuration to expand the URL of a
452
-    remote repository taking into account any "url.<base>.insteadOf" config
453
-    setting.
454
-
455
-    TODO: Replace current code with "git ls-remote --get-url" when the
456
-    continuous builders will support it. It requires the use of Git v1.7.5
457
-    or above. Beware that option "--get-url" of "git-ls-remote" is
458
-    supported since v1.7.5 (see https://github.com/git/git/commit/45781ad) but
459
-    was not properly documented until v1.7.12.2.
469
+    remote repository taking into account any "url.<base>.insteadOf" or
470
+    "url.<base>.pushInsteadOf" config setting.
471
+
472
+    TODO: Replace current code with something like "git ls-remote
473
+    --get-url" after Git grows a version of it that returns the push
474
+    URL rather than the fetch URL.
460 475
     """
461 476
 
462
-    url = git_config_get_value('remote.%s' % remote, 'url', '')
463
-    push_url = git_config_get_value('remote.%s' % remote, 'pushurl', url)
464
-    push_url = alias_url(push_url)
477
+    push_url = git_config_get_value('remote.%s' % remote, 'pushurl')
478
+    if push_url is not None:
479
+        # Git rewrites pushurl using insteadOf but not pushInsteadOf.
480
+        push_url = alias_url(push_url, False)
481
+    else:
482
+        url = git_config_get_value('remote.%s' % remote, 'url')
483
+        # Git rewrites url using pushInsteadOf or insteadOf.
484
+        push_url = alias_url(url, True)
465 485
     if VERBOSE:
466 486
         print("Found origin Push URL:", push_url)
467 487
     return push_url

+ 7
- 0
git_review/tests/test_git_review.py View File

@@ -418,6 +418,13 @@ class GitReviewTestCase(tests.BaseGitReviewTestCase):
418 418
                       'test_project_url')
419 419
         self._run_git_review('-l', '-r', 'alias')
420 420
 
421
+        self._run_git('config', '--unset',
422
+                      'url.%s.insteadof' % self.project_uri)
423
+        self._run_git('config', '--add',
424
+                      'url.%s.pushinsteadof' % self.project_uri,
425
+                      'test_project_url')
426
+        self._run_git_review('-l', '-r', 'alias')
427
+
421 428
 
422 429
 class HttpGitReviewTestCase(tests.HttpMixin, GitReviewTestCase):
423 430
     """Class for the git-review tests over HTTP(S)."""

Loading…
Cancel
Save