0

if I create a new branch all the commits from the copied branch are coppied to the new one.

How can I stop this? I would like to have just new commits in the new branch..

Anorak
  • 3,096
  • 1
  • 14
  • 11
Betty Sanchez
  • 219
  • 3
  • 11
  • 2
    Please tell us about the commands you are using. It seems to me you are misunderstanding some concepts. – Sascha Wolf Aug 11 '14 at 10:58
  • I'm using egit in eclipse and whenever I click new branch from development branch (for example) when I go to my online repo as I watch the commit history on the new branch I see all the previous commits from the dev branch. All my branches end up with the same commits because when I merge the feature branches to the development branch same thing happens. – Betty Sanchez Aug 11 '14 at 11:02
  • git checkout development / git checkout-b "new branch" / git checkout development / git merge "new branch" – Betty Sanchez Aug 11 '14 at 11:03
  • 1
    This is the expected behaviour. When you create a new branch it will point to the commit you have currently checked out (if you don't specify a commit). The commits aren't copied, your new branch just points to the same commit as, for example, development does. What do you want to achieve? – Sascha Wolf Aug 11 '14 at 11:05
  • Yes I understand that it must point to the commit the problem is that it points to all commits in the development branch. and not just the last one. is this normal? I would like to just have the last commit from the dev branch and all the new commits in this new one and when I merge I would like to have only the merge commit and not the history of commits in the new branch I would like to leave the history of commits of the new branch in the branch and just the result in the dev branch when merging – Betty Sanchez Aug 11 '14 at 11:10
  • Just to be sure I understand the last part correctly. You don't want to have the new commits all in the development branch after merging but rather a single merge commit which combines the changes? I will talk about your first point in an answer. – Sascha Wolf Aug 11 '14 at 11:14
  • yes a single merge with all changes in the new branch from the first commit. – Betty Sanchez Aug 11 '14 at 11:26
  • I found the answer to this last point on this thread : http://stackoverflow.com/questions/3697178/git-merge-all-changes-from-another-branch-as-a-single-commit. – Betty Sanchez Aug 11 '14 at 11:28

2 Answers2

2

Commits in git contain a reference on their parent commit. This is how git builds the history of your repository.

A branch on the other hand just points to a specific commit. It is literally a file which contains the SHA-1 key of the current commit. You can find them in the .git/refs/heads folder in your repository.


When you create a new branch without specifying a commit the branch will point to the same commit HEAD currently points at. (Note that HEAD doesn't directly point at a commit but at a branch, but that's a different story.)

Let's assume you are currently on your development branch and want to create a new branch to work on a new feature.

git checkout -b new-branch

Now both development and new-branch will point at the same commit, lets say the key is DEF456. This commit contains a reference to it's parent commit - as every commit does - which is ABC123 which in turn again contains a reference on it's parent commit and so on.

You see, git doesn't copy the history of a branch when creating a new branch, it just points to the same commit as the current branch does.

If you want to learn more about how git stores it's information internally you can take a look at the Git Objects chapter of the gitpro book.


And as you already found in this question. You can force a merge commit, rather than a fast-forward, by using git merge --no-ff <branch-to-merge>.

A merge commit is special in the sense that it doesn't contain one refence on a parent commit, as most commits in git do, but it contains multiple references to it's parent commits. This defines a merge.

Community
  • 1
  • 1
Sascha Wolf
  • 18,810
  • 4
  • 51
  • 73
  • 2
    I think the term "branch" is the source of much confusion for Git beginners. It's really a misnomer, in many respects. – jub0bs Aug 11 '14 at 14:16
  • @Jubobs Never thought about that but it makes a lot of sense. The term implies that a branch provides some extra functionality although git already brings everything on the table to branch heavily. Maybe "link" would have been the better choice, or something in this direction. – Sascha Wolf Aug 11 '14 at 16:47
  • 1
    @Zeeker *Link*, *pointer*, *reference* (although people use *branch reference*, which is fine by me) would be preferable to *branch*. I actually asked a [question](http://stackoverflow.com/questions/25068543/what-exactly-do-we-mean-by-branch) about the term "branch", recently. It (and the answers to it) may be of interest to you. – jub0bs Aug 11 '14 at 16:58
2

It sounds like you were really asking about forcing "real" merges rather than "fast forward" merges, and about "squash" merges (which are not actual merges at all). For completeness, though, I want to mention that there's one more thing you can do when creating a new branch-name:

git checkout --orphan -b newbr

In this case, git puts you on newbr without actually creating newbr yet. This means that the next commit will start a new, independent commit-graph within your repository. In other words, you will have multiple "root commits" in a single repository (a root commit is a commit that has no parents, vs ordinary commits that have one parent and merge commits that have two or more parents).

Multiple independent commit graphs within a repository are unusual, but supported: git's own source repository contains them, for instance. (The git program is maintained using git.)

torek
  • 448,244
  • 59
  • 642
  • 775
  • TIL and I'm curious. What would be a usecase for multiple, independent commit-graphs? – Sascha Wolf Aug 11 '14 at 20:29
  • 1
    @Zeeker: in the case of the git repo, gitk and git-gui were initially independent. Grab the repo (git://git.kernel.org/pub/scm/git/git.git) and use `git log --oneline --max-parents=0` to see the roots. – torek Aug 11 '14 at 20:34