Compare two or more repo directories

hustnzj發表於2022-09-13

Differences conclusion

We have discussed three ways to get a bare repository from a normal one and we conclude their differences:

  • Manual operation is complicated and error-prone but it retains all the remote-tracking branches and all the related configuration variables.
  • The methods using git clone with --bare or --mirror options are both easier and safer but --bare lost related configuration variables and remote-tracking branches and --mirror lost related configuration variables.

Repositories Comparison Detail

In order to find exact differences among them, we should have an experiment of comparing the directories of the bare repositories produced above.

Here is our playground.

➜  bare-repo-experiments git:(daily) ✗ ll
total 0
drwxr-xr-x  20 administrator  staff   640B Sep 12 21:50 repo
drwxr-xr-x  10 administrator  staff   320B Sep 12 23:08 repo_clone_bare.git
drwxr-xr-x  10 administrator  staff   320B Sep 12 23:09 repo_clone_mirror.git
drwxr-xr-x  16 administrator  staff   512B Sep 12 21:59 repo_manual.git

In the bare-repo-experiments directory, repo is my normal repository, repo_manual.git, repo_clone_bare.git and repo_clone_mirror.git are all bare repositories made by the methods mentioned in here respectively.

Then we can use diff to compare the differences of the three bare repository directories.

diff --recursive --from-file=repo_manual.git repo_clone_bare.git repo_clone_mirror.git

Note:

  • --recursive option is to recursively compare any subdirectories found.
  • --from-file option is to compare all the other directories with this specific one.

The result as below:

Only in repo_manual.git: COMMIT_EDITMSG
Only in repo_manual.git: FETCH_HEAD
Only in repo_manual.git: ORIG_HEAD
diff --recursive --from-file=repo_manual.git repo_manual.git/config repo_clone_bare.git/config
5d4
<     logallrefupdates = true
9,23c8
<     url = https://<domain-name>/hustnzj/my-git-repo
<     fetch = +refs/heads/*:refs/remotes/origin/*
< [branch "master"]
<     remote = origin
<     merge = refs/heads/master
< [remote "john"]
<     url = http://<domain-name>/hustnzj/johns-repo.git
<     fetch = +refs/heads/*:refs/remotes/john/*
< [remote "central"]
<     url = ../central-repo.git
<     fetch = +refs/heads/*:refs/remotes/central/*
< [credential]
<     helper = store
< [tar "tar.xz"]
<     command = xz -c
---
>     url = ~/bare-repo-experiments/repo
Only in repo_manual.git: filter-repo
Only in repo_manual.git: index
Only in repo_manual.git/info: refs
Only in repo_manual.git: logs
diff --recursive --from-file=repo_manual.git repo_manual.git/packed-refs repo_clone_bare.git/packed-refs
4,33d3
< e3e4b9d2bb6754fb64ad2e88071e923f49596203 refs/remotes/central/master
< e389021c2a677c74cef45607913d481cf523c2ff refs/remotes/john/pink-page
< c327903d6e9a3c536002e32cc35b3fa92b9d6c94 refs/remotes/origin/master
< ec47c3cfb2ae6e273c9e1a3c425afe81caeb8c80 refs/replace/0983fe6e1aa1381858fafd692ac46933a78fe425
< 4ad6c1b27e9982abb72833b55a9f41f90e5be6a9 refs/replace/0de1df17e33d943169c479c7cd904dc64170dfcf
< fb9d4e1dde6bb49a519d81ed6697843fb0124fee refs/replace/16ad5d399f9f9207f0fbb146277b9364b8d2daed
< e1899f5fb264509822805a3a81709313a013a3f5 refs/replace/1fd8a501ea5412b6fefd1c77bffb4ff4bff3fdf4
< 7e3a3979873314d2a388464bcc16b64cac337518 refs/replace/29e3d91d4488cb552a2d0e8048f4cc4fb5214ef8
< e68e62cb60987d75d5ded3065e418eb62ff80e54 refs/replace/41a835c45f532d104b47554ad7eaadd8648cfbe5
< f6e110dc715aeb0e44867a8007edef32f615baed refs/replace/42c821437af5489054ef9c045f1fa4593144a104
< 425d13b64693047402c8a5b27b36ede073be5e3b refs/replace/45f3a0bc19998f3bf7a68926e442740b48a50cdd
< 9e0815eedf21ddd2b85bdee10bd2db49f491606a refs/replace/49a8f479ab51851c7f01e7be1f2c90305964104d
< 3d7610d20b6d30a6a264d784ac69bbdf0a1a6c30 refs/replace/4f4d6cc8588e59701290e7b177daa89df56ade0d
< f94a846261b55b4f7b79c3ad880559c0e3e6270d refs/replace/6d2604d2afaa486ae2c66383fa7aada76474604a
< 11dba213c6cd9cdd0733a8f8a508e27d7be3bca8 refs/replace/70641bd0c370893d6244b678bdade24d4de70120
< f1bca4eb7bbf9fbf2fa9f0ce89df1f06d1481aa9 refs/replace/72a3391d6dbb48593e87cda117ad9aa31794c57b
< 306d7fde2bf982644044b80c0fd4852773d1ce46 refs/replace/7b7c9f08aa0ec0a68bc859e9585ca76862f78e27
< 447ecde5956735d5188fbdbd17d4fba4de1e9c36 refs/replace/830f3e6ba37d69726963d2818977f3efbbad1852
< 260dca88ac3fbf6ae1411a063f12cc9ee9d0d86f refs/replace/b1c2d16d1931f8a0fe08acd6368390e08722207a
< 353ef3fa73a4834610c6f9251e80cdadbc831add refs/replace/b4d098b3ab1d3ee17f53fec6a0a0e3729dabb40d
< 628ce50022f7891c8c4365b28b7a90611b69c962 refs/replace/b5d4bad9617d72089ce745e846af97f6f725cddf
< af7c805c7bbbb3dd8e342854ab42a6139fb43b08 refs/replace/bda6a121c2a8f737ac97fc034690199eba4490b1
< d4805cebe2aa6f48a8cce04275a98c175484b0ec refs/replace/be753ffa0b78dbfd8fbec6a7a3c734a348d2dfca
< 94a2c54df363a7defce092a4aa3cf1821f5e1302 refs/replace/c2300cb5cbe3f8899862895f03e080da0b018ac1
< 8c255787f4d4be5e32b7f336ccdde6374ada62f9 refs/replace/ce5905531b5b4860de5daa210dc37e9b55f0a6d1
< 9c8dbcd3ee44b36fd83e682b9d276f872fd1e7c7 refs/replace/e99d67de154b10cff89a7041050f6a5e16e420dc
< fc61641ce6fe7601fad545caca4dbd7674ff963e refs/replace/fd24aaa01b34bb3f77e1787c41e2a6a18cee1923
< 5aec55c631cc06ac9fb20f730ca133444a3b1f19 refs/replace/ff7f6c0a3aa007d9156ce0d5a4ea8068a00411b9
< d30e517f1577fe60669022a069189e8c696ee441 refs/replace/fff89ffa8a77ca21dc632a9ee4da600a03135bd5
< 26d88458afa512b06d435709ed01a864fdd07c42 refs/stash
Only in repo_manual.git/refs: remotes
Only in repo_manual.git/refs: replace
Only in repo_manual.git/refs: rewritten
Only in repo_manual.git: COMMIT_EDITMSG
Only in repo_manual.git: FETCH_HEAD
Only in repo_manual.git: ORIG_HEAD
diff --recursive --from-file=repo_manual.git repo_manual.git/config repo_clone_mirror.git/config
5d4
<     logallrefupdates = true
9,23c8,10
<     url = https://<domain-name>/hustnzj/my-git-repo
<     fetch = +refs/heads/*:refs/remotes/origin/*
< [branch "master"]
<     remote = origin
<     merge = refs/heads/master
< [remote "john"]
<     url = http://<domain-name>/hustnzj/johns-repo.git
<     fetch = +refs/heads/*:refs/remotes/john/*
< [remote "central"]
<     url = ../central-repo.git
<     fetch = +refs/heads/*:refs/remotes/central/*
< [credential]
<     helper = store
< [tar "tar.xz"]
<     command = xz -c
---
>     url = ~/bare-repo-experiments/repo
>     fetch = +refs/*:refs/*
>     mirror = true
Only in repo_manual.git: filter-repo
Only in repo_manual.git: index
Only in repo_manual.git/info: refs
Only in repo_manual.git: logs
diff --recursive --from-file=repo_manual.git repo_manual.git/packed-refs repo_clone_mirror.git/packed-refs
5a6
> c327903d6e9a3c536002e32cc35b3fa92b9d6c94 refs/remotes/origin/HEAD
Only in repo_manual.git/refs: remotes
Only in repo_manual.git/refs: replace
Only in repo_manual.git/refs: rewritten

From this result above, we can see that although we compare three directories in one command line, in effect, diff still compare two directories each time. This comparison still follow these rule: diff directory1 directory2 and diff file1 file2.

When comparing two files, e.g., in the diff --recursive --from-file=repo_manual.git repo_manual.git/config repo_clone_bare.git/config, repo_manual.git/config is file1, repo_clone_bare.git/config is file2.

In the comparing result, the content after < is in file1 and the content after > is in file2.

Now we can understand the conclusion at the top section.

Further Reading

本作品採用《CC 協議》,轉載必須註明作者和本文連結
日拱一卒

相關文章