git的一个烦恼是必须使用git remote add upstream URL
来制作一个从一些上游仓库(例如Github forks)分叉的repo的每个克隆。理想情况下,我应该能够将上游位置存储在forked repo本身中,以便所有克隆自动设置它。有没有办法用git完成这个?
答案 0 :(得分:2)
就Git本身而言,原始仓库(即你分叉的仓库)与你的叉子的克隆之间没有联系;后者不包含有关前者URL的信息。因此,无论如何,您必须在克隆之后将原始仓库添加为克隆的远程。
为了使事情自动化并避免每次都输入URL,您只需为分叉的每个项目定义一个别名:
git config alias.remaddfoo "remote add upstream <URL-of-original-project-foo>"
克隆你的fork后,你必须在新克隆中cd
并记住调用相应的别名。
进一步采取自动化将涉及在git clone
周围编写某种包装器,它将自动cd
在克隆内并运行git remote add...
,但解析git clone
&#39正确的论证可能有点过于复杂。
答案 1 :(得分:2)
正如其他答案所述,git目前没有将repos链接在一起的内置功能。</ p>
因此,我编写了一个名为clone
的小型Python脚本,它使用BeatifulSoup 4解析BitBucket和GitHub的上游存储库,并将其添加为名为upstream
的远程数据库。这适用于git和Mercurial。它是hosted on GitHub,但为了完成,我在这个答案中包含了完整的脚本:
#! /usr/bin/env python3
description='''
A wrapper for repo cloning commands for various DVCS.
Automatically adds the upstream URL when cloning a forked repo from
popular DVCS web hosts.
Currently supports:
(DVCS: git, Mercurial)
(hosts: GitHub, Bitbucket)
'''
# Created by Jesse Johnson a.k.a. holocronweaver (2014-10-08).
import argparse
import re
import subprocess
import urllib.request
from bs4 import BeautifulSoup
def find(regex, string, errorMessage):
'''Return value at regex, or else print error message and exit program.'''
m = re.search(regex, string)
if (m):
return m.group(1)
else:
print('Error:', errorMessage)
exit()
parser = argparse.ArgumentParser(description=description)
parser.add_argument('origin', metavar='O', type=str,
help='the SSH URL of origin repo, optionally'
'followed by its destination folder')
args = parser.parse_args()
# Parse destination.
splitArgs = re.split('\s+', args.origin)
if len(splitArgs) > 1:
origin = splitArgs[0]
destination = splitArgs[1]
else:
origin = args.origin
destination = find('@.*\.\w+[:|/].*/(.*)[.git]?$', origin,
'Error: Could not parse destination folder from origin URL.')
destination = re.sub('\.git', '', destination)
print('destination folder:', destination)
# Unfortunately HTTPS URLs do not contain enough info to clarify which
# DVCS is being used, so SSH is easiest to support.
vcs = find('^[ssh://]?(.*)@', origin,
'URL does not contain SSH user (e.g., git@ or hg@).')
print('version control system:', vcs)
domain = find('@(.*\.\w+)[:|/]', origin,
'Error: Could not parse domain from origin URL.')
print('domain:', domain)
path = find('@.*\.\w+([:|/].*)[.git]?$', origin,
'Error: Could not parse repo path from origin URL.')
path = re.sub(':', '/', path)
print('repo path:', path)
homepage = 'https://' + domain + path
print(homepage)
data = urllib.request.urlopen(homepage).read()
soup = BeautifulSoup(data)
# Version control system specifics.
if ('git@' in origin):
ext = '.git'
clone = 'git clone %s %s'
setUpstream = 'git remote add upstream %s'
elif ('hg@' in origin):
ext = ''
clone = 'hg clone %s %s'
setUpstream = 'echo "upstream = %s \n" >> .hg/hgrc'
else:
print('Error: Version control system not supported.')
exit()
upstream = None
if ('github.com' in origin):
element = soup.find('span', class_='fork-flag')
if element:
upstreamBase = element.span.a['href']
upstream = 'https://github.com' + upstreamBase + ext
elif ('bitbucket.org' in origin):
element = soup.find('a', class_='fork-of')
if element:
upstreamBase = element['href']
upstream = 'https://bitbucket.org' + upstreamBase + ext
else:
print('Warning: Web host not supported.')
print('Warning: Continuing to clone without adding upstream repo.')
print(upstream)
subprocess.Popen(clone % (origin, destination), shell=True).wait()
if upstream:
subprocess.Popen(setUpstream % upstream, cwd=destination, shell=True).wait()
答案 2 :(得分:1)
默认情况下git clone
会调用您的远程“来源”。如果你想让它被称为其他东西,请使用
git clone -o upstream <path_to_repo>
--origin <name>
-o <name>
Instead of using the remote name origin to keep track of the upstream repository, use <name>.
编辑:对于需要跟踪遥控器遥控器的情况......我从来没有找到一个好方法来做到这一点。您可以在git clone
周围编写一个包装器,但必须对每个存储库进行硬编码。