I am a newbie to Git please pardon me if my question seems absurd. Can we switch branches without pushing the changes at the same time not losing the changes in the files of another branch.
I want to switch from main branch to another branch(say alpha). I have few files in the staging area of main branch. If I switch to alpha branch will I lose the changes made in the files in main branch
CodePudding user response:
There could be changes in 3 sections, changes to be committed, changes not staged for commit, and untracked files. Imagine that Git will apply these changes after you switch to another branch. If there is not any conflict, it switches to another branch and the changes are reserved as they were on the previous branch. If there is any conflict, the switching process is aborted, and an error is raised,
error: Your local changes to the following files would be overwritten by checkout:
<path_to_file>
Please commit your changes or stash them before you switch branches.
Aborting
In this case, you are still on the original branch and the changes are not lost, unless you specify -f/--force
in git checkout <branch>
or git switch <branch>
.
As the error suggests, you can commit the changes,
git add <paths>
git commit -m "some message"
or stash the changes,
git stash -u -m "some message"
# -u is to also stash the untracked files
Both methods save the changed files in the repository's database and make the working area clean. They are safe unless .git
gets corrupted. With a clean working area, switching to another branch always succeeds.
Later when you want to take the changes back, you could either run
git checkout main
git reset HEAD^
or
git checkout main
git stash apply --index
# or
git stash pop --index
# --index is useful when changes to be committed and changes not staged for commit both exist
Besides git commit
and git stash
, git worktree
is also a good choice if the Git version is v2.5 or above.
git worktree add /path/to/foo alpha
It creates a worktree /path/to/foo
and checks out the files of the branch alpha
in it. The worktree shares the repository's .git
with the main worktree (where main
is checked out). This way, the main worktree is not touched and the changes there are not affected at all. You can run git commands in /path/to/foo
to manipulate the branch alpha
. Do not create /path/to/foo
nested in the main worktree or in other repositories.
After you finish the job on alpha
, you can remove its worktree.
cd /path/to/mainworktree
git worktree remove /path/to/foo
or
rm -rf /path/to/foo
cd /path/to/mainworktree
git worktree prune
CodePudding user response:
You won't loose the changes if you switch branches unless you use explicit flags.
With git switch
.
Switching branches does not require a clean index and working tree (i.e. no differences compared to HEAD). The operation is aborted however if the operation leads to loss of local changes, unless told otherwise with --discard-changes or --merge.
With git checkout <branch>
:
To prepare for working on
<branch>
, switch to it by updating the index and the files in the working tree, and by pointing HEAD at the branch. Local modifications to the files in the working tree are kept, so that they can be committed to the<branch>
.
What happens:
- If the files you changed in
main
were not changed inalpha
then git will switch the branches and the local changes are undone. - If the files you changed in
main
were changed inalpha
then git will refuse the switch.
This behavior is often used when some work was done while being on main
branch and the work needs to be committed in a new branch e.g. feature_x
. With the changes in the working tree (the actual files) you can then git switch -c
or git checkout -b
to create a new branch and then commit the changes to this new branch.
If you do NOT want the current changes be still there when you switch to the alpha
there are 3 popular choices:
- Create a new branch and commit the changes and maybe push - the safest option - it's very hard to loose the changes with this approach. My favorite.
- Commit the changes to the current branch - often forgotten or not considered. IMO, this should be the default approach when on a feature branch (i.e. not
main
) - Stashing the changes with
git stash
- This option is popular, but stashed changes cannot be shared with others, stash entries don't have names by default (like branches) and it's relatively easy to loose the changes.
After any of these you can switch to alpha
and the changes will not be there.