I have two repositories: A and B. File doc.txt is located in A repository in A_master branch. Current B branch is B_master.
I created a branch based on A_master in A repository. I call it A_feature. I have also created a branch based on B_master in B repostory, B_feature. I commited doc.txt deletion in A_feature. I then commited same doc.txt addition in B_feature. Thus, moved doc.txt from A repository to B repository in *_feature branches. Afterwards, someone changes doc.txt in A_master. I am going to merge A_feature and B_feature.
- Will I lose doc.txt changes made in A_master? Why?
- Will I see conflicts in *_feature pull requests? Why?
CodePudding user response:
If I understand your problem correctly, branches A_feature and B_feature are in different repositories so they can't be merged with each other. So this scenario can't happen.
CodePudding user response:
A Git repository is, at its heart, a collection of commits. It's not about files (though commits hold files). It's not about branches (though branch names help us, and Git, find commits). It's really just a collection of commits.
A commit, in Git:
Is read-only. No commit can ever be changed! Not one single bit can be changed.
Is numbered, with a big ugly hash ID expressed in hexadecimal. The number is unique to that one commit: no other commit, anywhere, in any Git repository, can have that number. Any other Git repository that does use that number, uses it to hold a copy of that commit.
Contains a snapshot of all of your files (in a special, compressed, Git-only, de-duplicated format) and some metadata.
A branch name in Git simply holds the hash ID—the commit number—of one particular commit: the latest one for that branch. That's all it is, really: a name for one commit. As you make new commits in that branch, Git automatically replaces the stored hash ID with the latest one.
(The metadata within each commit joins them together so that, starting from the latest, Git can work backwards to every previous commit. So holding the hash ID of the latest commit is sufficient.)
The act of check out a commit causes Git to extract all the saved files that are in that commit. The saved files in the commit cannot be changed, and only Git itself is able to read them so we have to extract them to use them. Once extracted from Git, those files are not in Git any more. That is, the files you see and work with may have come out of a Git repository and a commit, but now they're just ordinary files.
Now that you know the above, you can see where there is an error in your description:
[I] moved
doc.txt
from A repository to B repository ...
It's literally impossible to move a file from one repository to another:
- Repositories don't hold files; they hold commits.
- Commits can't be changed. "Moving" a file implies that it's gone from one location, and now appears in another. So this would require changing the files inside some commits, and that's not possible.
You can copy a file that you've extracted from some A-repository commit into the working tree for your B* repository, use git add
to prepare it to go into a new commit in B, and run git commit
in B to add a new commit to B in which the file exists.
You can remove the file from your working tree in A and add the removal (git add
the removed file, or use git rm
to do the whole thing in one shot) and then make a new commit in A, to add a new commit to A in which the file doesn't exist. The file continues to exist in previous commits in A.
Afterwards, [I made and committed] someone changes [to]
doc.txt
inA_master
.
This implies you copied doc.txt
into the working tree for B, rather than "moving" (copying-and-then-removing) doc.txt
. The new additional commits you made in repository A hold the updated versions of doc.txt
. The previously-existing commits continue to hold the older versions.
I am going to merge
A_feature
andB_feature
...
This may be difficult: git merge
operates on the commits in one repository. You have two different repositories, A and B. If they contain the same starting commits—remember, Git is all about the commits, as found by their commit numbers—you may be able to load the currently-private-to-A commits into repository B, or the B commits into A, and then you may be able to run git merge
on these commits.
Note that while git merge
takes a branch name:
git checkout br1 # or git switch br1
git merge br2
these operations are fundamentally about the commits in the repository. The merge operation, git merge br2
, uses the name br2
to find the most recent commit for that branch. It then uses the commit metadata from the current commit, and the designated commit, and any predecessor commits as needed, to locate the common starting point commit—the merge base—from which the two branch-tips are descended.
If the commits aren't in the same repository, it's impossible to merge them in the first place.