How to move git repository with all branches from

2019-01-09 21:02发布

问题:

What is the best way to move a git repository with all branches and full history from bitbucket to github? Is there a script or a list of commands I have to use?

回答1:

You can refer to the GitHub page "Duplicating a repository"

It uses:

  • git clone --mirror: to clone every references (commits, tags, branches)
  • git push --mirror: to push everything

That would give:

git clone --mirror https://bitbucket.org/exampleuser/repository-to-mirror.git
# Make a bare mirrored clone of the repository

cd repository-to-mirror.git
git remote set-url --push origin https://github.com/exampleuser/mirrored
# Set the push location to your mirror

git push --mirror

As Noted in the comments by L S:

  • it is easier to use the Import Code feature from GitHub described by MarMass.
    See https://github.com/new/import
  • Unless... your repo includes a large file: the problem is, the import tool will fail without a clear error message. Only GitHub Support would be able to diagnose what happened.


回答2:

It's very simple.

Create a new empty repository in GitHub (without readme or licesne, you can add them before) and the following screen will show

Inside to import code option you paste your bitbucket URL's repo and voilà!!



回答3:

In case you couldn't find "Import code" button on github, you can:

  1. directly open Github Importer and enter the url. It will look like:
  2. give it a name (or it will import the name automatically)
  3. select Public or Private repo
  4. Click Begin Import

UPDATE: Recently, Github announced the ability to "Import repositories with large files"



回答4:

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

This helped me move from one git provider to another. At the end of it, all the commits were in the destination git. Simple and straight forward.

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

Once I was happy that the push had been successful to GitHub, I could delete the old remote by issuing:

git remote rm bitbucket


回答5:

I had the reverse use case of importing an existing repository from github to bitbucket.

Bitbucket offers an Import tool as well. The only necessary step is to add URL to repository.

It looks like:



回答6:

I realize this is an old question. I found it several months ago when I was trying to do the same thing, and was underwhelmed by the answers given. They all seemed to deal with importing from Bitbucket to GitHub one repository at a time, either via commands issued à la carte, or via the GitHub importer.

I grabulated the code from a GitHub project called gitter and modified it to suite my needs.

You can fork the gist, or take the code from here:

#!/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

Then, to use the script:

# create a list of repos
foo
bar
baz

# execute the script, iterating over your list
while read p; do ./bitbucket-to-github.rb -a -n $p; done<repos

# good nuff


回答7:

There is the Importing a repository with GitHub Importer

If you have a project hosted on another version control system as Mercurial, you can automatically import it to GitHub using the GitHub Importer tool.

  1. In the upper-right corner of any page, click , and then click Import repository.
  2. Under "Your old repository's clone URL", type the URL of the project you want to import.
  3. Choose your user account or an organization to own the repository, then type a name for the repository on GitHub.
  4. Specify whether the new repository should be public or private.
    • Public repositories are visible to any user on GitHub, so you can benefit from GitHub's collaborative community.
    • Public or private repository radio buttonsPrivate repositories are only available to the repository owner, as well as any collaborators you choose to share with.
  5. Review the information you entered, then click Begin import.

You'll receive an email when the repository has been completely imported.

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


回答8:

Simplest way of doing it

git remote rename origin repo_bitbucket

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

git push origin master

Once the push to GitHub is success ,delete the old remote by

git remote rm repo_bitbucket



回答9:

In case you want to move your local git repository to another upstream you can also do this:

to get the current remote url:

git remote get-url origin

will show something like: https://bitbucket.com/git/myrepo

to set new remote repository:

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

now push contents of current (develop) branch:

git push --set-upstream origin develop

You now have a full copy of the branch in the new remote.

optionally return to original git-remote for this local folder:

git remote set-url origin https://bitbucket.com/git/myrepo

Gives the benefit you can now get your new git-repository from github in another folder so that you have two local folders both pointing to the different remotes, the previous (bitbucket) and the new one both available.