git log contain commit for another branch, how to separate commit beween branch

0

Issue

How to separate changes between branch?
for example:

  1. I create new branch with name BRANCH-1, made a changes, and commit the changes
  2. I create new branch with name BRANCH-2, made a changes, and commit the changes.
  3. I create new branch with name BRANCH-3, made a changes, and commit the changes.

my problem is, BRANCH-2 contain commit & changes from BRANCH-1

and BRANCH-3 contain commit & changes from BRANCH-1 and BRANCH-2

how to separate the changes and commit on each branch?

Thanks

Solution

Those commits are in fact on all of those branches.

Consider the following. We start with a single branch named main. The name main locates one specific commit, with one specific hash ID H. (The real hash ID is some big ugly random-looking thing, hence the use of uppercase letters as stand-ins.)

Commit H contains two things:

  • a source snapshot—a full copy of every file as it appears in the latest commit; and
  • some metadata that holds stuff like the name and email address of the person who made the commit.

The metadata in commit H contains the hash ID of some earlier commit. We say that H points to the earlier commit, and the name main points to commit H:

            <-H   <--main

The hash ID inside H itself is that of some other commit, so let’s draw in that commit, which we’ll call G:

        <-G <-H   <--main

Of course, earlier commit G points to some yet-earlier commit F:

... <-F <-G <-H   <--main

and so on down the line. Eventually we run out of "earlier" commits because we hit the very first one. Getting slightly lazy about drawing the arrows, this gives us a more complete picture:

A--B--C--D--E--F--G--H   <-- main (HEAD)

The name HEAD tells us that we did a git checkout main.

Let’s now add one new branch name, such as develop. Git requires that a branch name contain the hash ID of some valid, existing commit. Which of these commits should we use? The most obvious candidate is the current and latest commit, H:

A--B--C--D--E--F--G--H   <-- develop, main (HEAD)

If we now check out develop, the special name HEAD, which remembers which branch name is the current branch, moves:

A--B--C--D--E--F--G--H   <-- develop (HEAD), main

We are still using commit H. We’re just using it through the name develop.

Which branch(es) are the commits on? All commits are, pretty obviously, on both branches.

When we make a new commit, Git will:

  • package up all of the source files as a new snapshot;
  • add some metadata, with the right name and email address from user.name and user.email (those can’t possibly be lies: they must be right!), "now" as the date-and-time, and so on.

Git will get the log message from us or from the -m argument, and will use the current commit as the place that the new commit will point backwards to:

                       I
                      /
A--B--C--D--E--F--G--H   <-- main

Because we are on branch develop, as git status will say, Git will store new commit I‘s hash ID into the name to which HEAD is attached, develop, like this:

                       I   <-- develop (HEAD)
                      /
A--B--C--D--E--F--G--H   <-- main

Which commits are on branch develop? All of them, just as before. It’s not the case that only commit I is on develop. All the commits are on develop. It’s just that commits up through H are also on main.

If we now git checkout main, Git will:

  • remove all the files that go with commit I;
  • extract all the files that go with commit H; and
  • attach HEAD to main.

The result is:

                       I   <-- develop
                      /
A--B--C--D--E--F--G--H   <-- main (HEAD)

Nothing has changed in the commits and branches in the repository, except for where HEAD is attached; but our working tree (and Git’s index or staging area) are now updated to match commit H again.

If we now create another new branch name topic, and switch to it, we get:

                       I   <-- develop
                      /
A--B--C--D--E--F--G--H   <-- main, topic (HEAD)

If we now make another new commit, we get:

                       I   <-- develop
                      /
A--B--C--D--E--F--G--H   <-- main
                      \
                       J   <-- topic (HEAD)

This is what branches are all about, in Git: they’re ways to find commits.

It is the commits that are all important. Each commit stores a full snapshot of every file, in a special, read-only, Git-only, compressed and de-duplicated form. So if commits H, I, and J all share most of their files, they literally share the files, even though each one has its own full copy. (This sharing is enabled because the contents are read-only.)

To see what changed in any given commit, Git simply follows the commit’s internal backwards arrow to its parent. That parent has a snapshot too. Whatever files are the same in both commits are not changed, and since Git is doing de-duplication, it can find this out very fast. For files that are changed, Git compares their content to see what changed, and shows you a diff (this is computed on demand, not stored in the commit).

To make branches be "independent", just start them all far enough back. Here, branch topic and branch develop both started from commit H on main. That means changes we made, and then used to make the snapshots I or J, aren’t reflected in the other commit, which started with copies of files from H.

(Later, if and when we go to merge branches develop and topic, commit H—the best shared commit, on both branches—will be very important.)

Answered By – torek

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave A Reply

Your email address will not be published.

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More