Reputation: 57
I have a question of how to go back to git and produce new versions from previous versions.
For example, let's say I have the following commit history in the main branch:
v1.0 - v1.1 - v1.2 - v2.0 - v3.0
Now let's suppose I have a client that is version v1.2 and need to fix a bug, however it is not yet able to go to version 2.0 onwards.
If I go back to version 1.2 using the git checkout command, create a branch and work on the fix as I do to commit to an old version?
I would like my sequence to look like this:
v1.0 - v1.1 - v1.2 - v1.3 - v2.0 - v3.0
Remembering that I am aware that the v1.3 fix will not be in v2.0 and v3.0
Upvotes: 0
Views: 121
Reputation: 487745
Remembering that I am aware that the v1.3 fix will not be in v2.0 and v3.0
That's not what you drew, though. To draw that, let's re-draw this as a series of commits—the things that Git actually stores:
tag:v1.0
|
v tag:v1.1
...--●--● |
\ v tag:v1.2
●--...--● |
\ v tag:v2.0
●--●--...--● |
\ v tag:v3.0
●--...--● |
\ v
●--...--●
\
●--... <-- master
Here, master
is a branch name, identifying the latest commit on branch master
. Each of the various tag:...
is a tag name, identifying the specific commit that constitutes the version released to someone.
You now want to go back and create a new branch name pointing to the same commit that tag:v1.2
points to. That's fine:
tag:v1.0
|
v tag:v1.1
...--●--● |
\ v tag:v1.2
●--...--● |
\ v tag:v2.0
●--●--...--● <------|------- release/1
\ v tag:v3.0
●--...--● |
\ v
●--...--●
\
●--... <-- master
Each solid ●
here stands in for a commit. Commits are real, actual, and very-concrete things in Git: each one has its own unique hash ID. Tag names and branch names are less-solid because they can be moved around. Tag names shouldn't be moved; moving one is kind of a violation of how they should be used. Branch names, however, move on their own. You might now git checkout release/1
to get the commit identified by both the names tag:v1.2
and release/1
, and then make a new commit, which we'll represent as ○
here:
tag:v1.0
|
v tag:v1.1
...--●--● |
\ v tag:v1.2
●--...--● |
\ v tag:v2.0
●--●--...--●--○ <---|------- release/1
\ v tag:v3.0
●--...--● |
\ v
●--...--●
\
●--... <-- master
Note how nothing else changed. Exactly two things did change:
○
, andrelease/1
identifies this new commit, because the branch name you have checked out moves automatically when you create a new commit.This new commit is not part of the chain of commits that lead up to master
. It stands on its own. You can make a new tag to remember its hash ID for the future, because hash IDs are big and ugly and not memorable to humans, if you like. You can make more new commits before you tag this one, if you like.
This is what version control is all about, in the end: it keeps every commit you ever made, so that you can go back to it, look at it, test out bugs on it, construct fixes to it if needed, and continue development.
If your question is "how", you've already answered it yourself: create a branch name pointing to the desired commit, then make new commits. For instance:
git checkout -b release/1 v1.2
and then begin working.
Upvotes: 3