📜 ⬆️ ⬇️

Subproject allocation in a separate repository on github

Recently, I was faced with the task of transferring a project folder from one repository to another on github. It sounds primitive, but if we consider what is given and what needs to be obtained, some nuances may arise.


So, what is given:



What needs to be done:



In theory, one could simply copy the entire repository with all its contents to a new place, and then simply delete those folders that are not needed. But this method is rather non-optimal and I didn’t particularly like it, so I decided to do otherwise.


I used the standard filter-branch git one. I took the following articles as a basis:



In this post I want to adapt the process a little for better perception.


Suppose, for example, that our repository is called movement-example , and the only folder that we want to transfer to a separate repository is folder-to-move . Then the steps that need to be done to prepare the transfer are as follows:


  1. git clone git@github.com:<user_or_organization>/movement-example.git
    It is better to make a new clone of the repository, even if you already have it downloaded. Better yet, make a clone from the local repository: git clone <path-to-movement-example> is much faster (thanks to ZyXI for the hint).
  2. cd movement-example
  3. git remote rm origin
    This is exactly the moment for which we made a new clone - now we are not afraid to break the original repository.
  4. git filter-branch --subdirectory-filter folder-to-move -- --all
    After performing this step, only the content of the folder-to-move will remain in your local repository, and the folder itself will no longer exist - all files contained in it now lie in the current directory (in movement_example ).
  5. mkdir folder-to-move
    mv * folder-to-move
    This is an optional step - if you want to have all the files inside the same folder as before, and not in the root of the new repository.
  6. git add .
  7. git commit -m “Preparing to extract folder”

The first part is ready, and the second is to make the actual transfer. Suppose the new repository is simply called new-repo , then the necessary steps are as follows:


  1. git clone git@github.com:<user_or_organization>/new-repo.git
    We clone a new repository for ourselves, if, of course, we still have not done so.
  2. cd new-repo
  3. git remote add old-repo-branch <path-to-movement-example-folder>
    Add a new remote. If your new-repo and movement-example folders are at the same level in the file system, then the path-to-movement-example-folder would look like ../movement-example
  4. git pull old-repo-branch master
    After completing this step, the goal will be practically achieved - you will already have all the folder-to-move content in the local new-repo repository, all you have to do is push. But first you need to do something else.
  5. git remote rm old-repo-branch
    You don't need a second remote anymore, right?
  6. git push origin master

Done! Now, in your new repository there is only a folder of interest along with the entire history of commits. For example, immediately after the above steps, I saw the following in my new repository:


810 commits!


By the way, you will see only 1 brunch - master . The procedure transfers only one brunch at a time. If you want to transfer dev , then you just need to do git checkout dev and git pull origin dev after the second step in both steps.


If you need to transfer all 50 (60? 100?) Brunch, then this solution will not be successful because of too much routine work. But I think that for transfer, you just need to save the master and dev branches, because all the feature branches should already be in dev, and you will branch out new branches in the new repository.


UPDATE

Thanks fstep for the hint. You can simply use another guitar utility, the subtree . All you need is nothing:


  1. git clone <path-to-movement-example>
  2. git remote rm origin
    Please note - these 2 steps are optional, you can perform the following steps directly from your "combat" local repository. Having a clone with a remote origin is my personal preference to not even have a chance to somehow break the original repository.
  3. git subtree split --prefix folder-to-move master
    Or any other brunch, except master . This command will calculate the values ​​for a long time, but in the end it will return you something like 253f8a5edd9a4dbbb1d72e5837243e93c92ebfcd
  4. git push git@github.com:<user_or_organization>/new-repo.git 253f8a5edd9a4dbbb1d72e5837243e93c92ebfcd:master --force
    Here we push with the --force flag, because new-repo will probably have at least a readme file that you (probably) don’t want to pull.

Well, if new-repo is completely fresh and does not even contain the readme file - in other words, it does not contain any files at all, then it is still easier:


git subtree push --prefix folder-to-move git@github.com:<user_or_organization>/new-repo.git master


')

Source: https://habr.com/ru/post/326132/


All Articles