将具有所有分支和完整历史记录的git存储库从bitbucket移动到github的最佳方法是什么?我需要使用脚本或命令列表吗?

评论

Github为此提供了工具和文档:help.github.com/articles/…help.github.com/articles/…

聚会晚了一点,但是这里有一个迁移脚本:gist.github.com/chinmaya-n/cff02f1277c811deab2e550f2aad9967

#1 楼

您可以参考GitHub页面“复制存储库”

,它使用:



git clone --mirror:克隆每个引用(提交,标签,分支机构)

git push --mirror:推送所有内容

这将给: LS:


使用MarMass描述的GitHub上的Import Code功能更容易。
请参见https://github.com/new/import

除非...您的存储库中包含一个大文件:问题是导入工具将失败,并且没有明确的错误消息。只有GitHub支持人员才能诊断出发生了什么。


评论


这种方法给我带来了一个问题(不确定是否有问题)。当我将存储库从bitbucket镜像到github时,对于5个分支,它在github中显示为“ Compare and Pull Request”。它没有在github中显示为分支。我该怎么办?

– Siddharth
2014年7月6日在2:55

那问题和维基呢?

–弗拉迪斯拉夫·拉斯特鲁斯尼
2014-10-25 13:45

@FractalizeR Wiki只是另一个仓库,您也可以复制它(github.com/blog/699-making-github-more-open-git-backed-wikis)。但是,没有简单的方法可以复制问题。您需要使用Api(各种GitHub存储库备份程序都这样做:addyosmani.com/blog/backing-up-a-github-account)

–VonC
2014年10月25日16:04

如果您也想将存储库从Github移至Bitbucket,则此方法有效。

– Simeg
16年4月24日在5:46

我需要使用此方法来复制存储库,因为它包含一个大文件(> 100MB)。 GH不允许在其存储库中使用大文件。在将存储库推送到GH之前,我删除了大文件。但是,除其他问题外,使用GH的“导入存储库”功能在95%的时间内都是正确的选择,如另一个答案所述。但是,如果失败,它不会给出有用的错误消息,您必须联系GH支持。 GH支持使我知道了文件大小限制。

– Lance E Sloan先生
17年11月9日在16:28



#2 楼

非常简单。


在GitHub中创建一个新的空存储库(没有自述文件或许可证,您可以稍后添加它们),然后将显示以下屏幕。


在导入代码选项中,粘贴您的Bitbucket存储库的URL并贴上!!!!




评论


您实际上是在这里回答问题,因为接受的答案仅显示与Git相关的通用方法。您的答案更简单!

– Emile Bergeron
15年1月28日在16:21

只要您是创建存储库的人,这个答案就不错了。如果其他人为您创建了存储库(例如,负责分支创建的管理员),则此操作将无效。接受的答案是在这种情况下的解决方法。

– Master.Aurora
15年4月27日在7:45

前往考虑使用此方法的任何其他人,在使用此服务之前,请在先前的存储库主机上删除双因素身份验证,否则,您将陷入尝试删除GitHub中新创建的存储库的无休止循环中,并且摆脱这种情况的唯一方法是将URL末尾的/ import替换为/ settings以访问设置并将其删除。

–戴夫
16年5月12日在11:51

小警告-如果您遇到问题,则不会收到描述性错误消息。

– RobertH
16年7月26日在20:19

95%的时间使用GH的“导入存储库”功能是正确的选择。但是,如果失败,它不会给出有用的错误消息,您必须联系GH支持。我无法将其用于一个存储库,因为它包含一个大文件(> 100MB)。我需要使用可接受的CLI方法,就在将存储库推送到GH之前删除了大文件。

– Lance E Sloan先生
17年11月9日在16:22



#3 楼

如果您在github上找不到“导入代码”按钮,可以:


直接打开Github Importer并输入url。它看起来像:

给它一个名字(否则它将自动导入该名称)
更新:
最近,Github宣布了“导入具有大文件的存储库”的功能。

评论


不幸的是,这对我尝试从codebasehq转到git-hub无效,给出了“不支持此URL”。 :(

– sjmcdowall
2015年9月21日在12:22

@sjmcdowall抱歉,没有,但是我相信它应该可以正常工作,因为codebasehq URL指向git存储库。

– Biniam
2015年9月21日14:57在

URL不再存在。

–编码容器
16年5月24日在13:51

我刚刚检查的@CodedContainer,它可以工作。我什至刚刚更新了屏幕截图。

– Biniam
16年5月24日在14:02

如果您尚未登录GitHub,则该网址只会返回404。如果您已登录,则将加载导入工具。

–Jason Hurt
16年5月26日在6:16

#4 楼

http://www.blackdogfoundry.com/blog/moving-repository-from-bitbucket-to-github/

这帮助我从一个git提供程序迁移到另一个git提供程序。最后,所有提交都在目标git中。简单而直接。发行:

git remote rename origin bitbucket
git remote add origin https://github.com/edwardaux/Pipelines.git
git push origin master



评论


请在您的答案中包括链接的相关部分,因为它应该能够独立存在。

–k0pernikus
15年2月16日在10:46

我收到一个错误消息:“错误:无法将Som refs推送到'url.gi'提示:更新被拒绝,因为远程包含您在本地没有的工作。这通常是由另一个存储库推送到相同的ref引起的。您可能需要先集成远程更改(例如pull ...),然后再再次推送,有关详细信息,请参阅git push --help中有关快进的注释。

–编码容器
16年5月24日13:54

这是唯一在3/3/2019仍然有效的答案:)

–王望六
19 Mar 3 '19 at 23:48

#5 楼

我有一个反向用例,即从github将现有存储库导入到bitbucket。

Bitbucket还提供了一个Import工具。唯一必要的步骤是将URL添加到存储库。

如下所示:



#6 楼

我意识到这是一个老问题。几个月前,当我尝试做同样的事情时,我发现了它,但给出的答案不知所措。它们似乎都处理一次通过点菜发出的命令或通过GitHub导入器从Bitbucket导入到GitHub的存储库的问题。对其进行了修改,以满足我的需要。

您可以派出要点,或从此处获取代码:脚本:

#!/usr/bin/env ruby
require 'fileutils'

# Originally  -- Dave Deriso        -- deriso@gmail.com
# Contributor -- G. Richard Bellamy -- rbellamy@terradatum.com
# If you contribute, put your name here!
# To get your team ID:
# 1. Go to your GitHub profile, select 'Personal Access Tokens', and create an Access token
# 2. curl -H "Authorization: token <very-long-access-token>" https://api.github.com/orgs/<org-name>/teams
# 3. Find the team name, and grabulate the Team ID
# 4. PROFIT!

#----------------------------------------------------------------------
#your particulars
@access_token = ''
@team_id = ''
@org = ''


#----------------------------------------------------------------------
#the verison of this app
@version = "0.2"

#----------------------------------------------------------------------
#some global params
@create = false
@add = false
@migrate = false
@debug = false
@done = false
@error = false

#----------------------------------------------------------------------
#fancy schmancy color scheme

class String; def c(cc); "\e[#{cc}m#{self}\e[0m" end end
#200.to_i.times{ |i| print i.to_s.c(i) + " " }; puts
@sep = "-".c(90)*95
@sep_pref = ".".c(90)*95
@sep_thick = "+".c(90)*95

#----------------------------------------------------------------------
# greetings

def hello
  puts @sep
  puts "BitBucket to GitHub migrator -- v.#{@version}".c(95)
  #puts @sep_thick
end

def goodbye
  puts @sep
  puts "done!".c(95)
  puts @sep
  exit
end

def puts_title(text)
   puts  @sep, "#{text}".c(36), @sep
end

#----------------------------------------------------------------------
# helper methods

def get_options
  require 'optparse'

  n_options = 0
  show_options = false

  OptionParser.new do |opts|
    opts.banner = @sep +"\nUsage: gitter [options]\n".c(36)
    opts.version = @version
    opts.on('-n', '--name [name]', String, 'Set the name of the new repo') { |value| @repo_name = value; n_options+=1 }
    opts.on('-c', '--create', String, 'Create new repo') { @create = true; n_options+=1 }
    opts.on('-m', '--migrate', String, 'Migrate the repo') { @migrate = true; n_options+=1 }
    opts.on('-a', '--add', String, 'Add repo to team') { @add = true; n_options+=1 }
    opts.on('-l', '--language [language]', String, 'Set language of the new repo') { |value| @language = value.strip.downcase; n_options+=1 }
    opts.on('-d', '--debug', 'Print commands for inspection, doesn\'t actually run them') { @debug = true; n_options+=1 }
    opts.on_tail('-h', '--help', 'Prints this little guide') { show_options = true; n_options+=1 }
    @opts = opts
  end.parse!

  if show_options || n_options == 0
    puts @opts
    puts "\nExamples:".c(36)
    puts 'create new repo: ' + "\t\tgitter -c -l javascript -n node_app".c(93)
    puts 'migrate existing to GitHub: ' + "\tgitter -m -n node_app".c(93)
    puts 'create repo and migrate to it: ' + "\tgitter -c -m -l javascript -n node_app".c(93)
    puts 'create repo, migrate to it, and add it to a team: ' + "\tgitter -c -m -a -l javascript -n node_app".c(93)
    puts "\nNotes:".c(36)
    puts "Access Token for repo is #{@access_token} - change this on line 13"
    puts "Team ID for repo is #{@team_id} - change this on line 14"
    puts "Organization for repo is #{@org} - change this on line 15"
    puts 'The assumption is that the person running the script has SSH access to BitBucket,'
    puts 'and GitHub, and that if the current directory contains a directory with the same'
    puts 'name as the repo to migrated, it will deleted and recreated, or created if it'
    puts 'doesn\'t exist - the repo to migrate is mirrored locally, and then created on'
    puts 'GitHub and pushed from that local clone.'
    puts 'New repos are private by default'
    puts "Doesn\'t like symbols for language (ex. use \'c\' instead of \'c++\')"
    puts @sep
    exit
  end
end

#----------------------------------------------------------------------
# git helper methods

def gitter_create(repo)
  if @language
    %q[curl https://api.github.com/orgs/] + @org + %q[/repos -H "Authorization: token ] + @access_token + %q[" -d '{"name":"] + repo + %q[","private":true,"language":"] + @language + %q["}']
  else
    %q[curl https://api.github.com/orgs/] + @org + %q[/repos -H "Authorization: token ] + @access_token + %q[" -d '{"name":"] + repo + %q[","private":true}']
  end
end

def gitter_add(repo)
  if @language
    %q[curl https://api.github.com/teams/] + @team_id + %q[/repos/] + @org + %q[/] + repo + %q[ -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ] + @access_token + %q[" -d '{"permission":"pull","language":"] + @language + %q["}']
  else
    %q[curl https://api.github.com/teams/] + @team_id + %q[/repos/] + @org + %q[/] + repo + %q[ -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ] + @access_token + %q[" -d '{"permission":"pull"}']
  end
end

def git_clone_mirror(bitbucket_origin, path)
  "git clone --mirror #{bitbucket_origin}"
end

def git_push_mirror(github_origin, path)
  "(cd './#{path}' && git push --mirror #{github_origin} && cd ..)"
end

def show_pwd
  if @debug
    Dir.getwd()
  end
end

def git_list_origin(path)
  "(cd './#{path}' && git config remote.origin.url && cd ..)"
end

# error checks

def has_repo
  File.exist?('.git')
end

def has_repo_or_error(show_error)
  @repo_exists = has_repo
  if !@repo_exists
    puts 'Error: no .git folder in current directory'.c(91) if show_error
    @error = true
  end
  "has repo: #{@repo_exists}"
end

def has_repo_name_or_error(show_error)
  @repo_name_exists = !(defined?(@repo_name)).nil?
  if !@repo_name_exists
    puts 'Error: repo name missing (-n your_name_here)'.c(91) if show_error
    @error = true
  end
end

#----------------------------------------------------------------------
# main methods
def run(commands)
  if @debug
    commands.each { |x| puts(x) }
  else
    commands.each { |x| system(x) }
  end
end

def set_globals

  puts_title 'Parameters'

  @git_bitbucket_origin =   "git@bitbucket.org:#{@org}/#{@repo_name}.git"
  @git_github_origin = "git@github.com:#{@org}/#{@repo_name}.git"

  puts 'debug: ' + @debug.to_s.c(93)
  puts 'working in: ' + Dir.pwd.c(93)
  puts 'create: ' + @create.to_s.c(93)
  puts 'migrate: ' + @migrate.to_s.c(93)
  puts 'add: ' + @add.to_s.c(93)
  puts 'language: ' + @language.to_s.c(93)
  puts 'repo name: '+ @repo_name.to_s.c(93)
  puts 'bitbucket: ' + @git_bitbucket_origin.to_s.c(93)
  puts 'github: ' + @git_github_origin.to_s.c(93)
  puts 'team_id: ' + @team_id.to_s.c(93)
  puts 'org: ' + @org.to_s.c(93)
end

def create_repo
  puts_title 'Creating'

  #error checks
  has_repo_name_or_error(true)
  goodbye if @error

  puts @sep

  commands = [
      gitter_create(@repo_name)
  ]

  run commands
end


def add_repo
  puts_title 'Adding repo to team'

  #error checks
  has_repo_name_or_error(true)
  goodbye if @error

  puts @sep

  commands = [
      gitter_add(@repo_name)
  ]

  run commands
end

def migrate_repo

  puts_title "Migrating Repo to #{@repo_provider}"

  #error checks
  has_repo_name_or_error(true)
  goodbye if @error

  if Dir.exists?("#{@repo_name}.git")
    puts "#{@repo_name} already exists... recursively deleting."
    FileUtils.rm_r("#{@repo_name}.git")
  end

  path = "#{@repo_name}.git"
  commands = [
    git_clone_mirror(@git_bitbucket_origin, path),
    git_list_origin(path),
    git_push_mirror(@git_github_origin, path)
  ]

  run commands
end

#----------------------------------------------------------------------
#sequence control
hello
get_options

#do stuff
set_globals
create_repo if @create
migrate_repo if @migrate
add_repo if @add

#peace out
goodbye


#7 楼

可以使用GitHub Importer导入存储库

如果您有一个项目托管在另一个版本控制系统上,如Mercurial,则可以使用GitHub Importer工具将其自动导入到GitHub。


在任何页面的右上角,单击,然后单击导入存储库。
在“您的旧存储库的克隆URL”下,键入要导入的项目的URL。
选择您的用户帐户或组织来拥有存储库,然后在GitHub上输入存储库的名称。
指定新存储库是公共的还是私有的。


公共存储库对GitHub上的任何用户都是可见的,因此您可以从GitHub的协作社区中受益。


查看输入的信息,然后单击“开始导入”。

您将收到储存库已完全导入时的电子邮件。


https://help.github.com/categories/importing-your-projects-to-github
https:/ /help.github.com/articles/importing-a-repository-with-github-importer/


#8 楼

如果您要将本地git存储库移动到另一个上游,也可以执行以下操作:

以获取当前的远程URL:



git remote get- url origin


将显示类似以下内容:
https://bitbucket.com/git/myrepo

设置新的远程存储库:


git remote set-url origin git@github.com:folder / myrepo.git


现在推送当前(开发)分支的内容:


git push --set-upstream origin development


您现在在新的远程服务器中具有分支的完整副本。
(可选)返回此本地文件夹的原始git-remote: br />
给您带来的好处,您现在可以从github的另一个文件夹中获取新的git-repository,这样您就有两个本地文件夹都指向不同的遥控器,前一个(bitbucket)和新的都可用。

#9 楼

我制作了以下bash脚本,以便将我的所有Bitbucket(用户)存储库都作为私有存储库克隆到GitHub。

要求:


jq(命令-行JSON处理器)| MacOS:brew install jq步骤:


转到https://github.com/settings/tokens并创建访问令牌。我们只需要“回购”范围。


move_me.sh脚本保存在工作文件夹中,并根据需要编辑文件。


不要忘记CHMOD 755


运行! ./move_me.sh


享受节省的时间。



注意:


它将在脚本所在的目录(您的工作目录)中克隆BitBucket存储库。


此脚本不会删除您的BitBucket存储库。



需要移至GitHub上的公共存储库吗?
在下面找到"private": true并将其更改为"private": false
移动组织的存储库?离开。

快乐移动。
#!/bin/bash

BB_USERNAME=your_bitbucket_username 
BB_PASSWORD=your_bitbucket_password

GH_USERNAME=your_github_username
GH_ACCESS_TOKEN=your_github_access_token

###########################

pagelen=$(curl -s -u $BB_USERNAME:$BB_PASSWORD https://api.bitbucket.org/2.0/repositories/$BB_USERNAME | jq -r '.pagelen')

echo "Total number of pages: $pagelen"

hr () {
  printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -  
}

i=1

while [ $i -le $pagelen ]
do
  echo
  echo "* Processing Page: $i..."
  hr  
  pageval=$(curl -s -u $BB_USERNAME:$BB_PASSWORD https://api.bitbucket.org/2.0/repositories/$BB_USERNAME?page=$i)
  
  next=$(echo $pageval | jq -r '.next')
  slugs=($(echo $pageval | jq -r '.values[] | .slug'))
  repos=($(echo $pageval | jq -r '.values[] | .links.clone[1].href'))
  
  j=0
  for repo in ${repos[@]}
  do
    echo "$(($j + 1)) = ${repos[$j]}"
    slug=${slugs[$j]}
  git clone --bare $repo 
  cd "$slug.git"
  echo
  echo "* $repo cloned, now creating $slug on github..."  
  echo  

  read -r -d '' PAYLOAD <<EOP
  {
    "name": "$slug",
    "description": "$slug - moved from bitbucket",
    "homepage": "https://github.com/$slug",
    "private": true
  }
  EOP

  curl -H "Authorization: token $GH_ACCESS_TOKEN" --data "$PAYLOAD" \
      https://api.github.com/user/repos
  echo
  echo "* mirroring $repo to github..."  
  echo
  git push --mirror "git@github.com:$GH_USERNAME/$slug.git"
  j=$(( $j + 1 ))
  hr    
  cd ..
  done  
  i=$(( $i + 1 ))
done


评论


有趣的脚本,结合令牌。整齐。已投票。

–VonC
19/12/11在21:56

@VonC谢谢!

– cen
19年12月12日19:39

#10 楼

以下是移动私有Git存储库的步骤:

步骤1:创建Github存储库

首先,在Github.com上创建一个新的私有存储库。保持存储库为空非常重要,例如不要选中选项在创建存储库时使用README初始化该存储库。

步骤2:移动现有内容

接下来,我们需要用内容填充Github存储库从我们的Bitbucket存储库中:



从Bitbucket中查看现有存储库:

    $ git clone https://USER@bitbucket.org/USER/PROJECT.git



将新的Github存储库添加为该存储库的上游远程服务器。
从Bitbucket中检出: :仅仅是管理员),并标记了Github存储库:

    $ cd PROJECT
    $ git remote add upstream https://github.com:USER/PROJECT.git


步骤3:清理旧存储库

最后,我们需要确保开发人员不会因同一个项目具有两个存储库而感到困惑。以下是删除Bitbucket存储库的方法:


再次检查Github存储库是否具有所有内容
转到旧Bitbucket存储库的Web界面
选择菜单选项设置>删除存储库
将新Github存储库的URL添加为重定向URL

,此存储库就完全安置在Github的新家中了。让所有开发人员都知道!

#11 楼

最简单的方法:

git remote rename origin repo_bitbucket

git remote add origin https://github.com/abc/repo.git

git push origin master


一旦成功推送到GitHub,请运行以下命令删除旧的远程服务器: >