Reputation: 16278
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:
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.
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.
Thanks
Upvotes: 1
Views: 762
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 :
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.
git branch -r
to see the list of branches from MAIN
git log origin/branchname
to view the history of branchname
on MAIN
git log --decorate
, each commit will appear with the names of branches and tags pointing to itgitk
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