Home > Back-end >  Apply changes from one branch to another without affecting git history
Apply changes from one branch to another without affecting git history

Time:11-22

My question is, is it possible to reference a change made in branch A in a feature branch B, without having a duplicated commit or staged changes?

Then, when you merge this branch B into A, git would recognize that this referenced commit was already on A and doesn't do anything. Is there a command for this?

I know cherry-pick, rebase and merge,but those commands don't solve that problem.

I don't even know if it is possible regarding the git architecture, so I appreciate everyone who can help me out.

CodePudding user response:

With some minor exceptions, all that's in Git is the set of commits that are in Git. The history is the commits; the commits are the history; and that's all there is.

That means the straightforward answer to your question—once one reshapes it into one that fits in Git, that is; there aren't any branches in the sense that you mean the word, and there are not even any changes since commits are snapshots—is "no". All you can do is make another commit, or more than one additional commit, to add new saved states.

The minor exceptions include things like branch names: each name stores one hash ID, from which we find all the other commits. This forms a graph, specifically a Directed Acyclic Graph, with the branch and other names serving as entry points into the otherwise self-contained graph. This is how we find the commits in the repository.

To the extent that there are files in a repository, they exist only because they're contained in commits. Each commit has a full snapshot of every file (though stored in a weird, Git-ized, de-duplicated form so that commits that share the same file do in fact share the file: it's in all the commits, but everything is always done with a layer of indirection for sharing). So the names find particular commits, and those commits find the other commits and the contained files.

When you use git merge, you get:

  • a real merge: a new commit that adds to the graph (adds more history: its backwards link to a previous commit is a pair of links to two previous commits), or
  • nothing at all: a fake fast-forward merge that just moves a branch name; or
  • a "squash merge" via git merge --squash: Git does the same work as for a real merge but then stops and makes you make the new commit. The new commit doesn't link to two commits.

So only in the fake case—which is really just "move a branch name"—do you not add any commits; you can use that one, in one special case, to answer your question with "yes". You end up with both branch names selecting the same commit in this case; that one commit has the right snapshot and connects backwards to the desired previous commits so it suffices. But otherwise you'll have to add a commit.

  • Related