Source code migration (Github <=> Bitbucket)

What is a BARE git repository?
Understand the difference between BARE and NON-BARE repositories and learn how to migrate source code from one SCM(bitbucket) to another SCM(git) including all branches, tags and commit history.

Learn cherry-pick to push specific commit to another branch.

10_commands_for_scm_migration
1.clone_old_repo.sh

    git clone --mirror https://github.com/tvajjala/application.git NEW

2.change_working_dir.sh

    cd NEW

3.make_.git_folder.sh

    mkdir .git

4.move_files.sh

    mv info/ .git/ && mv description .git/ && mv hooks/ .git/ && mv refs/ .git/ && mv objects/ .git/ && mv config .git/ && mv packed-refs .git/ && mv HEAD .git/ && mv FETCH_HEAD .git/

5.make_non_bare.sh

    git config --local --bool core.bare false

6.make_it_working_repo.sh

    git reset --hard

7.remote_remote_origin.sh

    git remote rm origin

8.add_remote_origin.sh

    git remote add origin https://tvajjala@bitbucket.org/tvajjala/application.git

9.push_origin_all.sh

    git push origin --all

10.push_tags.sh

    git push --tags

What is a BARE git repository?

A bare Git repository is typically used as a Remote Repository that is sharing a repository among several different people. You don’t do work right inside the remote repository so there’s no Working Tree (the files in your project that you edit), just bare repository data.

What is the difference between a bare repository non-bare repository?

Non-bare repositories contains working directories. (git clone /git init)

In the top level folder of the repository you will find two things:

  1. A .git subfolder with all the git related revision history of your repo

  2. A working tree, or checked out copies of your project files.

Repositories created with --bare command are called bare repos.

bare_command.sh
git clone --bare <REPO_URL> <DESTINATION_FOLDER>

They are structured a bit differently from working directories.

  1. First off, they contain no working or checked out copy of your source files.

  2. Second, bare repos store git revision history of your repo in the root folder of your repository instead of in a .git subfolder.

Note
Let’s call the original repository ORI and the new one NEW, here after.

Following three simple steps help you to achieve this.

  1. Clone ORI into one temporary directory

  2. Convert BARE repository into non-bare repository (IMPORTANT)

  3. Point locally cloned repository to NEW remote repository and push your changes to NEW

Clone ORI into one temporary directory

There are different ways you can clone ORI

  • git clone origin-url (non-bare): You will get all of the tags copied, a local branch master (HEAD) tracking a remote branch origin/master, and remote branches origin/next, origin/pu, and origin/maint. The tracking branches are set up so that if you do something like git fetch origin, they’ll be fetched as you expect. Any remote branches (in the cloned remote) and other refs are completely ignored.

  • git clone --bare origin-url: You will get all of the tags copied, local branches master (HEAD), next, pu, and maint, no remote tracking branches. That is, all branches are copied as is, and it’s set up completely independent, with no expectation of fetching again. Any remote branches (in the cloned remote) and other refs are completely ignored.

  • git clone --mirror origin-url: Every last one of those refs will be copied as-is. You’ll get all the tags, local branches master (HEAD), next, pu, and maint, remote branches devA/master and devB/master, other refs refs/foo/bar and refs/foo/baz. Everything is exactly as it was in the cloned remote. Remote tracking is set up so that if you run git remote update all refs will be overwritten from origin, as if you’d just deleted the mirror and recloned it. As the docs originally said, it’s a mirror. It’s supposed to be a functionally identical copy, interchangeable with the original.

  • Create an empty directory and run below command to get everything from your ORI

clone_bare_repo_to_local
    git clone --mirror https://github.com/tvajjala/decision-tables.git NEW
Tip
you can use either --bare /--mirror , as per your needs.
  • Change working directory

   cd NEW
Caution
If you are trying to perform any normal git commands, you will get following error. since it is BARE repository.
error.sh
git checkout master
fatal: this operation must be run in a work tree

Convert BARE repository into non-bare repository

Run the below command in the ROOT directory to see the structure

bare_repo_structure
tvajjala$ls -lart
total 40
drwxr-xr-x   3 tvajjala  staff   96 Jun 30 15:06 ..
drwxr-xr-x   3 tvajjala  staff   96 Jun 30 15:06 info
-rw-r--r--   1 tvajjala  staff   73 Jun 30 15:06 description
drwxr-xr-x  13 tvajjala  staff  416 Jun 30 15:06 hooks
drwxr-xr-x   4 tvajjala  staff  128 Jun 30 15:06 refs
drwxr-xr-x   4 tvajjala  staff  128 Jun 30 15:06 objects
-rw-r--r--   1 tvajjala  staff  234 Jun 30 15:06 config
-rw-r--r--   1 tvajjala  staff  105 Jun 30 15:06 packed-refs
-rw-r--r--   1 tvajjala  staff   23 Jun 30 15:06 HEAD
drwxr-xr-x  11 tvajjala  staff  352 Jun 30 15:12 .
-rw-r--r--   1 tvajjala  staff  129 Jun 30 15:12 FETCH_HEAD
Tip
As mentioned earlier there is no .git folder and there is no source code folders.

1. Now, we need to move all folders inside the .git folder.

convert_to_non_bare
tvajjala$mkdir .git

tvajjala$ls -lart
total 40
drwxr-xr-x   3 tvajjala  staff   96 Jun 30 15:06 ..
drwxr-xr-x   3 tvajjala  staff   96 Jun 30 15:06 info
-rw-r--r--   1 tvajjala  staff   73 Jun 30 15:06 description
drwxr-xr-x  13 tvajjala  staff  416 Jun 30 15:06 hooks
drwxr-xr-x   4 tvajjala  staff  128 Jun 30 15:06 refs
drwxr-xr-x   4 tvajjala  staff  128 Jun 30 15:06 objects
-rw-r--r--   1 tvajjala  staff  234 Jun 30 15:06 config
-rw-r--r--   1 tvajjala  staff  105 Jun 30 15:06 packed-refs
-rw-r--r--   1 tvajjala  staff   23 Jun 30 15:06 HEAD
-rw-r--r--   1 tvajjala  staff  129 Jun 30 15:12 FETCH_HEAD
drwxr-xr-x   2 tvajjala  staff   64 Jun 30 15:41 .git
drwxr-xr-x  12 tvajjala  staff  384 Jun 30 15:41 .

tvajjala$mv info/ .git/ && mv description .git/ && mv hooks/ .git/ && mv refs/ .git/ && mv objects/ .git/ && mv config .git/ && mv packed-refs .git/ && mv HEAD .git/ && mv FETCH_HEAD .git/

tvajjala$ls -lart
total 0
drwxr-xr-x   3 tvajjala  staff   96 Jun 30 15:06 ..
drwxr-xr-x  11 tvajjala  staff  352 Jun 30 15:43 .git
drwxr-xr-x   3 tvajjala  staff   96 Jun 30 15:43 .

2. Run below command to convert the local git-repository to non-bare.

convert_to_non_bare
git config --local --bool core.bare false

3. Run below command to Reset the current repository

reset_repo
 vajjala$git reset --hard
 HEAD is now at <most_recent_commit_message>

 tvajjala$ls -lart
 total 80
 drwxr-xr-x   3 tvajjala  staff    96 Jun 30 15:06 ..
 -rw-r--r--   1 tvajjala  staff  3063 Jun 30 15:47 pom.xml
 -rw-r--r--   1 tvajjala  staff    89 Jun 30 15:47 .gitignore
 drwxr-xr-x   4 tvajjala  staff   128 Jun 30 15:47 src
 drwxr-xr-x  14 tvajjala  staff   448 Jun 30 15:47 .git
Tip
Now you can see source in the root directory ( ex: pom.xml/ build.gradle, src folders )

Point ORI to NEW Repository

  1. If you look at the current NON-BARE repository it is still pointing to OLD repository

check_remote_origin
tvajjala$git remote -v
origin https://github.com/<OLD_REPO.GIT> (fetch)
origin https://github.com/<OLD_REPO.GIT> (push)
  1. Run below command to remove , remote repository link

remove_origin
git remote rm origin
  1. Run below command to point to NEW Remote REPO

add_new_origin
tvajjala$git remote add origin https://tvajjala@bitbucket.org/tvajjala/documentation.git
  1. Finally run below command to see all your branches, tags and commit history in the new SCM repository , Enjoy!

push_to_new
git push origin --all

git push --tags

Summary

clone_old_repo.sh
git clone --mirror https://github.com/tvajjala/application.git NEW
change_working_dir.sh
cd NEW
make_.git_folder.sh
mkdir .git
move_files.sh
mv info/ .git/ && mv description .git/ && mv hooks/ .git/ && mv refs/ .git/ && mv objects/ .git/ && mv config .git/ && mv packed-refs .git/ && mv HEAD .git/ && mv FETCH_HEAD .git/
make_non_bare.sh
git config --local --bool core.bare false
make_it_working_repo.sh
git reset --hard
remote_remote_origin.sh
git remote rm origin
add_remote_origin.sh
git remote add origin https://tvajjala@bitbucket.org/tvajjala/application.git
push_origin_all.sh
git push origin --all
push_tags.sh
git push --tags

Cherry picking

Cherry picking in Git means to choose a commit from one branch and apply it onto another.

This is in contrast with other ways such as merge and rebase which normally apply many commits onto another branch.

  • Checkout feature branch

    git checkout feature/cherrypicking
  • Run below command to see commit hash tags

    git log --oneline
  • Checkout branch where you want to push (ex : master)

    git checkout master
  • Run below command to add specific commit to master branch

    git cherry-pick 3aef111

GIT commit delete permanently

Following steps helps us to delete commits permanently

What is the difference between reset and rebase

  • git-reset works with refs, on your working directory and the index, without touching any commit objects (or other objects).

  • git-rebase on the other hand is used to rewrite previously made commit objects.

deplicate_commit_history.sh
tvajjala$git log --oneline

4aca454 (HEAD -> master, origin/master) Commit we want to revert
c3293be Commit reverting
674d426 Separate log file per batch
558bd09 create seprate log per job
c1eb153 Spring boot batch initial commit
196fb6a simple spring batch
389faac Initial commit
reset_hard_last_two_commits.sh
tvajjala$git reset --hard HEAD~2

HEAD is now at 674d426 Separate log file per batch
tvajjala$git log --oneline
674d426 (HEAD -> master) Separate log file per batch
558bd09 create seprate log per job
c1eb153 Spring boot batch initial commit
196fb6a simple spring batch
389faac Initial commit
remote_branch_push.sh
tvajjala$git push origin +master

Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/tvajjala/spring-boot-batch.git
 + 4aca454...674d426 master -> master (forced update)

Comments

Popular posts from this blog

IBM Datapower GatewayScript

Spring boot Kafka Integration

Spring boot SOAP Web Service Performance