zupazt3
zupazt3

Reputation: 1046

Git - Push subfolder to different repository

I have a big repository with many files and projects. One of the sub-folders in this repo has to be a new, separated repository.

I don't need to preserve history in the new one, but I have to be able, at any time, to update new repo with changes from the original repo.

The idea is that the old repo is a private, internal gitlab and the new repo is a public repo for deployed project.

How can I do this?

Upvotes: 11

Views: 9343

Answers (3)

Petr Hudeček
Petr Hudeček

Reputation: 1763

If you only ever need to update the public repository from the private repository and never in the opposite direction, you can use:

C:\privateRepo> git subtree push --prefix=public ..\publicRepo publicBranch

This will copy all commits that access the subfolder public (and the copies will only contain information about files that are in that subfolder) and push those commits into the repository in C:\publicRepo at branch publicBranch.

Upvotes: 3

Marina Liu
Marina Liu

Reputation: 38096

You can treat the new repo as subtree for the old repo, and update new repo with old repo by git subtree push. Detail steps as below:

Assume the old repo has folders project1, project2, project3 etc for different projects. And the project1 has managed in the new repo.

Frist, replace the project1 folder in old repo by the new repo.

# Copy project1 folder out of old repo
# Delete the project1 folder in old repo, then use the commands in old repo
git add .
git commit -m 'delete project1 folder in old repo'
git subtree add --prefix=project1 <URL for new repo> master

Now project1 folder in old repo is the subtree from new repo. You can make change and commit (git commit) in old repo.

When you need to update the new repo by the old repo, you can use:

git subtree push --prefix=project1 <URL for new repo> master

Now the new repo will be updated.

Upvotes: 6

Mark Adelsberger
Mark Adelsberger

Reputation: 45659

The most "automatic" way to set this up is probably to use submodules. You can read about submodules here: https://git-scm.com/book/en/v2/Git-Tools-Submodules

I don't work much with submodules. I can tell you that people often trash-talk the feature, so you may want to consider whether it's worth it. But if you want direct git support for the idea that you modify the files in the context of the broader repo, and the more specific public repo receives the update, then this is the only way I can think of to get it.

So if you decide to use this approach, you would:

  • check out the appropriate version of the parent repo
  • initialize a new repo to serve as the child repo
  • move everything from the subdirectory of the parent repo work tree to the child repo work tree
  • commit the child repo
  • replace the subdirectory in the parent repo with a submodule reference

A little additional setup is needed to be able to push changes to the submodule; see the linked documentation page for all the details.

If a less "git-centric" approach is acceptable, then you could simply script the process of taking an update from the "parent" repo and applying it to the child repo. How hard that would be depends on your specific requirements. (Does an "update" just mean a new snapshot you've chosen to be tacked onto the child repo's master? Or during an update would you need to replicate the intervening history?)

If at any point you do need to script a transfer of history, you'll want to use git filter-branch with the subdirectory-filter option to create new commits, which you'll then fetch into the child repo and graft (probably using filter-branch again) onto the history tree.

Upvotes: 1

Related Questions