0

I have 3 git repos with similar organization and some duplicate directories between them. They are subprojects of one big project.

Proj1/
     .git/
     feature1_lib/
     feature1_app/
     feature1/       <- specific to Proj1

     feature2_lib/
     ...

Proj2/
     .git/
     feature1_lib/
     feature1_app/
     feature1/       <- specific to Proj2

     feature2_lib/
     ...

Proj3/
     .git/
     feature1_lib/
     feature1_app/
     feature1/       <- specific to Proj3

     feature3_lib/   <- specific to Proj3
     feature3_app/   <- specific to Proj3
     feature3/       <- specific to Proj3
     ...

They was developed simultaneously, but have slightly different history.

Proj1/
      ...
      commit4   "Commit specific to Proj1."
      commit5   "Add code to feature1_lib."
      commit6   "Fix bugs in feature1_lib."
      commit7   "Refactoring in feature1_lib."
      ...

Proj2/
      ...
      commit6   "Import changes from Proj1."   <- after commit7 in Proj1
      commit7   "Commit specific to Proj2."
      commit8   "Fix bugs in feature2_lib."
      commit9   "Add code to feature2_lib."
      ...

and so on.

Now I am seeking for options to cut and glue duplicated parts. I think it should look like this

Proj1_2_common/
     .git/
     ...
Proj1_2_3_common/
     .git/
     ...
Proj1/
     .git/
     ...
Proj2/
     .git/
     ...
Proj3/
     .git/
     ...

I read about subtree and submodule, but do not fully understood. Why I have to make subtree if I can just point in my projects to certain directory? That is, instead of making subtree from "feature1_lib/" I can simply reconfig my projects to look into "Proj1_2_3_common/feature1_lib/".

So what is the better options here from yours point of view? What is the easiest one? How to deal with such messy history to have some references after movement?

LVitya
  • 528
  • 4
  • 11

1 Answers1

2

You should manage your application in an other way :

  1. Create a repository for each project
Proj1/
  .git
Proj2/
  .git
Proj3/
  .git
  1. Create a repository for all modules/features
ProjModules/
  .git
  feature1/
  feature2/
  feature3/
  1. Use Git submodules to include your feature in your 3 projects :
Proj1/
  .git
  .gitmodules
  vendor/
    ProjModules/
Proj2/
  .git
  .gitmodules
  vendor/
    ProjModules/
Proj3/
  .git
  .gitmodules
  vendor/
    ProjModules/

Then, you can make changes in Proj1/vendor/ProjModules and propagate these changes in Proj2/ and Proj3/ :

$ cd /Proj1/vendor/ProjModules/
$ touch newfile.txt
$ git add --all
$ git commit -m "New file !!"
$ git push origin master

$ cd ../../../Proj2/vendor/ProjModules/
$ git submodule foreach git pull

$ cd ../../../Proj3/vendor/ProjModules/
$ git submodule foreach git pull

Another idea would be to create a repository per module. This would allow you to only import the one you need.

zessx
  • 68,042
  • 28
  • 135
  • 158
  • `1.` I have it. `2.` I need to cut it from original repos. `3.` Why submodules is better option here? What about history? – LVitya Sep 23 '14 at 09:54
  • @LVitya With submodules, changes made to `*/vendor/ProjModules` will be affected to the `ProjModules` project's history. It's the same behavior than if you were switching to `ProjModules` to make your changes, and then switching back to `Proj*` to pull these changes. From now, `ProjModules` history belongs to `ProjModules` project, and `Proj*` history belongs to `Proj*` project. – zessx Sep 23 '14 at 09:58
  • What is the difference vs subtree? How can I save previous history of changes in detached directories? – LVitya Sep 23 '14 at 11:01
  • Subtree come with a few improvements over submodules, but you're not concerned as long as you work alone on your project. These improvements essentially concern the fact that if you push submodule's edits, no one (using your main project) knows there were edits. Subtree solve this, enforcing the link between main project and modules. – zessx Sep 23 '14 at 11:49