0

Let's say I have a repository and it's a straight line. I checkout the very first commit and I add a file and commit it. Will this create a new branch implicitly? If it does and I merge it back into the parent, what happens to all the commits that are based on the parent? How do I go back in the history make a change and have it propagate to all future commits based off of it?

2

3 Answers 3

1

I checkout the very first commit and I add a file and commit it. Will this create a new branch implicitly?

No. In Git, when you checkout a commit, it updates the content of your working directory to match the content of that commit. You can look around and play with it, but you cannot commit changes. This is called the detached HEAD state.

In this state you can create a branch with git checkout -b branchname, so that you will be in a proper branch, commit changes, and diverge from the original branch.

If it does and I merge it back into the parent, what happens to all the commits that are based on the parent?

Let's say you created a branch from the 1st commit, and you want to merge this independent branch into the original. The commits in the original branch don't change. The unique commits in the new branch will be appended to the original branch, their changes will be applied to the files.

The result will look something like this:

$ git log --graph --oneline --decorate * 69d6cc5 (HEAD, master) Merge branch 'mybranch' |\ | * 01ca942 (mybranch) added something * | e715c4a 3rd commit * | 4f88705 2nd commit |/ * e7a9e79 Initial commit 

How do I go back in the history make a change and have it propagate to all future commits based off of it?

This is called rebasing, and it's best to avoid as much as possible. Rebasing rewrites the history. If you think about it this is against the spirit of version control, where existing commits should be left alone, immutable, and all changes should be incremental. However, Git let's you do this, you're the boss. This sequence of commands will do it:

# create branch from a specific older commit git checkout -b mybranch SOMESHA # work work work git commit -m 'fixed something important' # switch to the master branch git checkout master # rebase on top of mybranch git rebase mybranch 

That's it. This will rewind the history of master to the tip of mybranch, and apply all the changes that happened in master after SOMESHA one by one.

Sticking with the earlier example repo, the result will look something like this:

$ git log --graph --oneline --decorate * 7e3dd9d (HEAD, master) 3rd commit * 027589b 2nd commit * 01ca942 (mybranch) added something * e7a9e79 Initial commit 

Notice that the first commit and the one in mybranch have the same SHA1 as earlier, but the 2nd and 3rd commits have different SHA1. Even though their content is actually the same. We rewrote history. Whether you merge or rebase, the end result should be the same in terms of the content of the files.

Another reason to avoid rebasing is that after you do this, you must tell all users who have cloned your repository to force update their clones. This can be confusing, and a serious inconvenience for them.

Sign up to request clarification or add additional context in comments.

2 Comments

Ok. So if rebase is not advisable, then what is the alternative if you're patching up code that changes and it isn't in a repo repo you can easily pull from? In other words, you patch their files, and then their new release clobbers your changes. Git makes C++ look like BASIC!
"Not advisable" doesn't mean "never ever use it". Avoid if you can. Use it if you must. The alternative is merging. The end content should be the same either way. Rebase just reorders revisions. It's mostly for the pedantic, I think. Cosmetic stuff.
0

I checkout the very first commit and I add a file and commit it. Will this create a new branch implicitly?

It gets appended to the end of the current LOCAL branch. Assuming you have a REMOTE branch, they will differ.

If it does and I merge it back into the parent, what happens to all the commits that are based on the parent

The LOCAL and REMOTE branches differ, you will have to merge/rebase when you want them to be in sync again, and push the local branch to the remote one to update it to everyone else.

How do I go back in the history make a change and have it propagate to all future commits based off of it

You don't, if you rewrite history locally and push it you will have to tell everyone else that uses the remote branch to delete their local branch and pull yours. You should never do that, just update your local branch with a merge or a rebase just before pushing it to REMOTE to everyone else.

Comments

0

When you check out a commit (as opposed to a branch), you go into ‘detached HEAD’ state. This means that when you make subsequent changes to your HEAD (using git commit, git reset, etc.), this will not automatically update any branch. Also, your HEAD will not be visible in gitk once it isn't the parent of a branch or tag any more, which might be confusing.

Your master branch isn't affected by this, which means you will lose all work done in this state once you check out the master branch (unless you write down the commit id or retrieve it from the reflog).

If you want to create a new branch, you will have to do so explicitly:

git checkout -b new_branch_name 

You can merge your changes back into the master branch as usual:

git merge master new_branch_name 

How do I go back in the history make a change and have it propagate to all future commits based off of it?

There are two ways to achieve this:

  • Use git rebase -i and change the command from pick to edit for the appropriate line(s). Make sure you don't delete any lines here since that will drop the commits.
  • Proceed as above, then use git rebase new_branch_name master to rebase your old master branch on top of the new branch. Optionally do git branch -d new_branch_name.

You shouldn't ever change the history of a public repository, though.

2 Comments

Are you checking out from the master branch? Also, when merging back to master, do all of its child branches get updated as well? I.e. Master is version 1 and a version 2 branch based on it, does version to get affected by the branch?
No, you will have to merge to each branch individually. However, I would strongly discourage changing the history of an old (released?) version. The only situation where this is appropriate is when you accidentally included binary or confidential information in the repository, in which situation git filter-branch is a more appropriate tool.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.