Vasiliy
Vasiliy

Reputation: 16278

Find out in which repository the commit was added

We have two git repositories containing two distinct, but very similar projects.

The first project is the main project (MAIN hereinafter), and the second project is a derivation from MAIN (DERIV hereinafter).

EDIT: Please note that these are not different branches in the same repo, but two separate repos. In each repo we maintain just one branch master.

We work on these two projects in parallel, but the basic assumption is that every change to MAIN should also be applied to DERIV. We satisfy this by issuing periodical pulls from MAIN to DERIV.

The questions:

  1. When executing git log in DERIV, can I see, for each commit, in a clone of which repository it was added?

    EDIT: The question is whether this is doable while both repos maintain a single branch master. If not, then the question becomes whether using different names for branches in two repos will solve this issue.

  2. Can I find out the dates of pulls from MAIN to DERIV?

    EDIT: The issue with git log is the following: when I work on MAIN project, I clone from MAIN repo to a local machine, do some work (multiple commits), pull from MAIN and resolve conflicts (if any), push to MAIN/master. The last commit's message is Merge branch 'master' of MAIN. When I pull from MAIN to DERIV and resolve the conflicts the message is Merge branch 'master' of MAIN - the same as above. I would like to know in a clone of which repo was the above (merge-resolution) commit added.

  3. Can I see who performed a pull from MAIN to DERIV?
  4. Do you think that pulling from MAIN is the best approach? For instance, the same results could be achieved with cherry-picking (and, maybe, rebase).

Thanks

Upvotes: 1

Views: 762

Answers (1)

LeGEC
LeGEC

Reputation: 52236

[EDIT : following updated question]

If you register both remotes, you can see which commits are registered on MAIN and which are registered on DERIV.

$ git clone gitserver:deriv.git
$ cd deriv
$ git remote add main gitserver:main.git
$ git fetch main

You should see a branch main/master in your local repo, which will tell you which commits are part of MAIN and which aren't.

[/EDIT]

Short answer :

  1. yes
  2. no, but it probably doesn't matter
  3. no, but it probably doesn't matter
  4. yes

about git log :

I assume you started your DERIV repository by running git clone MAIN DERIV, and that you want a workflow where you pull from MAIN, but never push.

In that case, the DERIV repository is "aware" of the existence of MAIN, and git commands (mainly git fetch) allow you to integrate MAIN's history into DERIV.

Each time you run git fetch (git pull is actually git fetch followed by git merge), you will import MAIN's history into DERIV, and its current branches will be visible and tagged with the origin/ prefix.

  • you can run git branch -r to see the list of branches from MAIN
  • you can run git log origin/branchname to view the history of branchname on MAIN
  • if you run git log --decorate, each commit will appear with the names of branches and tags pointing to it
  • these annotations will also appear in graphic tools like gitk

You can then spot which branches in your DERIV projects have integrated changes from the MAIN project.

If you have some branches in DERIV tracking branches in MAIN (it is the default behavior of master), git status will inform you if DERIV's branch is missing commits from MAIN's branch.

If you mainly use the command line, two commands are very handy :

git log --graph --decorate --pretty=oneline --abbrev-commit
git log --graph --decorate --pretty=oneline --abbrev-commit --all

You can add them as shortcuts in your config file.

about who pulled and when

You will see the dates and authors of MAIN's commits, you will see the dates and authors of merges in DERIV's commits, when there will be conflicts with MAIN. You won't see exactly who pulled the history in though.

git fetch is actually a (almost) harmless command which will import MAIN's history and not meddle with DERIV branches (what it will do is add a bunch of commits to your repository, and move all the origin/* branches which are imported).

pull vs cherry-pick

It's easier to track differences between branches head (git has all this internal mechanism for tracking and merging branches) than to try to achieve the same result by hand (e.g. : using cherry-pick and rebase, and try to track by hand which commits have been ported and which have not).

What else ?

git fetch / git merge / git pull is definitely the way to go to keep the two repositories in sync. What you need is a set of rules for branches.

Maybe you are only interested in some particular branches of MAIN (master, release, ...) and not in other ones (dev, test, tmp ...) : you can configure your DERIV repository to import only some selected branches by default (details here).

It is handy to have local branches mirroring remote branches, but maybe you don't want DERIV:master to be "hard-linked" to MAIN:master.

If you want to unlink master and origin/master, you can edit the .git/config file and remove the section [branch "master"].

If you want to create a local branch which tracks a remote branch with a different name, you can run :

git branch main/v10 --track origin/v10

main/v10 will be a local branch, which tracks the remote v10 branch.

Conclusion

A git answer is rarely complete without pointing to The Book. Take the time to read it, it has a very high relevant explanation / line of text ratio. Chapter 3 is about branching and merging.

Upvotes: 5

Related Questions