2

I have a Git repository d:\repositories\temp and a directory d:\temp1, and I want to achieve this: All changes in the directory d:\temp1 can be detected and committed to the repository d:\repositories\temp (local and remote). Is it possible? Thanks.

Note: The feature I need here may be similar as the external links of SVN.

Ray Chen
  • 182
  • 1
  • 2
  • 13
  • About the content of temp1: should it be compared to the full content of the repo ? or to a subfolder of the repo ? – LeGEC Mar 01 '17 at 08:14

2 Answers2

4

You can declare d:\temp1 as:

  • a repository itself (git init .) in order to record its changes
  • a submodule of d:\repositories\temp

    git submodule add -b master -- /d/temp1
    git submodule update --init
    

See "true nature of submodules":

  • temp1 would become a subfolder of d:\repositories\temp,
  • any change made in d:\temp1 can be committed, and updated in d:\repositories\temp\temp1 after a git submodule update --remote

That way, at any point, temp records the exact state of temp1 it is working with (I prefer that to a subtree)
As I mentioned in "SVN:externals equivalent in GIT?", this is close to svn:external, even though it is not completely the same.

Note that if you push temp to GitHub, you will see temp1 as a gray folder: That gray folder is a gitlink (a special entry in the parent index)

If you clone that GitHub repo with the --recursive option, you will get back the content of temp1, because Git will be able to clone back /d/temp1.
...
However, nobody else would be able to clone your GitHub repo and get that temp1 content, since they don't have access to your /d disk!

In order to preserve the content of a submodule, it is best if temp1 itself is first pushed to its own GitHub repo, and temp reference temp1 through its GitHub url (and not through a local path /d/temp1).
See here to change the url of submodule temp1.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thanks for the detailed reply. When I executed the command `git submodule add -b master -- d:\temp1` at `d:\repositories\temp`, the following message display "repo URL: 'master' must be absolute or begin with ./|../", do you know how to resolve it? Thanks. – Ray Chen Mar 01 '17 at 08:06
  • @RayChen try instead a relative path: `../../temp1` – VonC Mar 01 '17 at 08:13
  • Hi, VonC. The messages changed as `"fatal: repository 'https://github.com/temp1/' not found"` and `"fatal: clone of 'https://github.com/temp1' into submodule path 'temp1' failed"`. – Ray Chen Mar 01 '17 at 08:18
  • @RayChen what `git remote -v` (done in both repo) return? Are those repos cloned from GitHub? – VonC Mar 01 '17 at 08:24
  • The `d:\temp1` is only a local Git here, it has no remote. I don't know whether this fact causes this error. – Ray Chen Mar 01 '17 at 08:24
  • 1
    What if you use `/d/temp1` as the submodule path? – Pockets Mar 01 '17 at 08:26
  • Running the command `git remote -v` at `d:\repositories\temp` returns `origin https://github.com/raychen518/temp.git (fetch)` and `origin https://github.com/raychen518/temp.git (push)`, while running at `d:\temp1` returns nothing (there is no any display). – Ray Chen Mar 01 '17 at 08:27
  • @RayChen maybe try a specify the protocol: `file://../../temp1` – VonC Mar 01 '17 at 08:28
  • @Pockets Thanks. I run the command `git submodule add -b master -- /d/temp1` and it seemed succeeded. A folder named `temp1` and a file named `.gitmodules` were created under `d:\repositories\temp`. But that folder `temp1` does not contain content of `d:\temp1`, do you know why? – Ray Chen Mar 01 '17 at 08:37
  • @VonC Thanks for the update. I created a directory `d:\temp2` and follow your updated steps again. This time there is no error, but the created `temp2` folder under `d:\repositories\temp` is still empty (the directory `d:\temp2` actually has some content). Do you know why? Thanks. – Ray Chen Mar 01 '17 at 09:00
  • @RayChen You need to add and commit in `temp2` first, then go back to `'d:\repositories\temp`, and do a `git submodule update --remote` (then, since temp2 SHA1 will have changed, add, commit and push) – VonC Mar 01 '17 at 09:01
  • @vonc FWIW The reason it has to use the Unix-style filepath is because Git for Windows runs on top of the MSYS2 POSIX emulation environment. – Pockets Mar 01 '17 at 16:45
  • @Pockets True. I should have known, I documented that a long time ago: http://stackoverflow.com/a/35099458/6309, http://stackoverflow.com/a/17810334/6309, http://stackoverflow.com/a/3144417/6309 – VonC Mar 01 '17 at 16:57
  • @VonC Thanks for your patient help. I created several new directories and followed the updated steps again, now after I changed and committed (only to local) content in those new directories, I can get that changed content in corresponding directories under `d:\repositories\temp`. But, when I commit `d:\repositories\temp` to remote, only those corresponding directories are committed, content of them are not committed. And I checked the remote at GitHub, those gitmodule directories are there but cannot be clicked into, and they are displayed with strange suffixes (such as @ fb9038d). – Ray Chen Mar 02 '17 at 02:54
  • @RayChen I have edited the answer to address the gray folder issue. Also, re-read http://stackoverflow.com/questions/1979167/git-submodule-update/1979194#1979194 to understand what submodules are all about. – VonC Mar 02 '17 at 05:18
  • @VonC Thanks for the update. I have seen that updated answer and basically understand it. Maybe finally I will create a batch file to copy all external files to the repository and then commit (_because I do not want to create remote Git repositories for all my external files which are under different unrelated directories, it is troublesome for me_). Let me consider it~ Thanks greatly for all the help. ^_^ – Ray Chen Mar 02 '17 at 06:52
1

Git has a feature called submodule that can be used to achieve what you are trying to achieve, Here have a look at this https://git-scm.com/book/en/v2/Git-Tools-Submodules

Rahul Kumar
  • 5,120
  • 5
  • 33
  • 44