-1

I cloned a master repo and created a branch using git checkout branchname1 made some changes and commited and pushed to remote repo then opened a new git bash terminal and switched to another aleady existing remote branch using git checkout branchname2 then ran git pull and made some changes there in two config files and committed and pushed the changes to remote repo ( note that I have not merged any branch into master yet). Now I came back to the previous terminal where I had branchname1, I see that my terminal is automatically poiting to branchname2 ( I dont know why ) so I tied to switch to brancname1 because I wanted to make more changes as soon as I type git checkout branchname1 It showed me one of the file names ( that I changed in branchname2 in second gitbash terminal ) and an M before it indicating the it has been merged to my branchname1 from branchname2. So I want to as 3 questions:

  1. why gitbash is automatically pointing to beanchname2 in the first terminal
  2. Why it is automatically merging changes from and committed branch ( branchname2)
  3. why it is merging only 1 file and not both files that I changed in branchname2 in the second terminal.

My Remote repos are gitlab repos.

Vicky
  • 1,298
  • 1
  • 16
  • 33

1 Answers1

0

TL;DR

You have something you did not commit. Git allows switching branches even with uncommitted work—sometimes. It's tricky (see Checkout another branch when there are uncommitted changes on the current branch for the gory details).

Long

If you're familiar with the Model-View-Controller software design pattern, consider that each of your Terminal windows are views of sorts. Git commands you run in some window manipulate content. The view in the other window eventually updates, later, when you come back to it. So you used git checkout as a controller in window 2 to alter the state, and then you were surprised when window 1 had altered state—but you should not have been.

In any case:

I cloned a master repo

In Git, there is really no such thing as a "master" repository. All repositories are complete copies of everything,1 and all repositories are therefore peers. We often like to pretend that some particular clone is "more equal", though, so let's assume that's the case with your Gitlab repo here.

Note that when you do clone a repository, you get all of their commits and none of their branches.2 Your Git takes all of their Git's branch names and turns those into remote-tracking names. For instance, if they have a main, their main becomes your origin/main. Only after all of this is done does your Git go on to create one branch in your clone. Git can do this because branches, in Git, don't actually matter much at all. What matter in Git are commits. Branch names are just a way for humans, and Git, to find commits. (This becomes crucial as soon as you make any new commits. Until then, the remote-tracking names will do the job.)

and created a branch using git checkout branchname1

Yes: note that this depends on the existence of a remote-tracking name (origin/branchname1). Your Git discovers this name exists, and creates your own new branch name, setting it up to locate the same commit.

made some changes and committed

I will assume here that this all went well—a slightly dangerous assumption given what happens afterwards.... The new commit gets a new, unique hash ID—the hash ID is the "true name" of any given commit—and Git writes that hash ID into your branch name, so that branchname1 now finds that commit.

and pushed to remote repo

Note that this sends, from your Git to theirs, the new commit. They and you now have the same commit, with the same hash ID. Your Git has their Git create or update some name—possibly their branchname1—to locate this new commit.

Let's take a breath now and get these footnotes out of the way, then resume the long bits.


1There are some exceptions to this rule: you can deliberately create a shallow and/or single-branch clone, where you don't get everything on purpose. But that's not the normal case.

2Again, this is not quite technically right, for more reasons than just the shallow and single-branch ones in footnote 1, but it's good for getting a mental model going for Git.


Back to what you were doing

then opened a new git bash terminal

(No real need: you just have one repository here, with one thing going on in it at a time.)

and switched to another already existing remote branch using git checkout branchname2

As before, this is actually going to create a new branch name in your local Git repository. You now have both branchname1 and branchname2. The creation of branchname2 happens during the git checkout of the commit located via the name origin/branchname2 (I'm assuming you are using the standard origin name here), and now your local branch name branchname2 specifies that same commit as your origin/branchname2, which is the same commit their Git told your Git that they were using as their branch name branchname2.

then ran git pull

If you ran git pull with no arguments here, your Git ran the equivalent of:

git fetch origin && git merge origin/branchname2

at this point. The git fetch has your Git call up the other Git using the URL stored under origin, and get from them any commits they have, that you don't. (They probably don't have any new commits, unless the branchname1 work took a while and/or the repository is highly active.) The subsequent git merge would incorporate any new commits they have on their branchname2 with your commits on your branchname2, but in this case, we would expect this to do nothing.

A slightly faster way to do this is to run git fetch first, then git checkout branchname2, which omits the merge step. Here we update the local repository first so that origin/branchname2 updates if needed, and only after that's complete (and as soon after as possible) do we create our own branchname2.

and and made some changes there in two config files and committed and pushed the changes to remote repo ...

We can presume that you did in fact make at least one new commit, and did the appropriate git push. But git status would, at this point, have shown at least one file that had uncommitted work in it.

Now I came back to the previous terminal where I had branchname1 [but is now on branchname2]

(because it's just a view into the same directory, in which the repository's current branch is now branchname2)

as soon as I type git checkout branchname1 It showed me one of the file names ( that I changed in branchname2 in second gitbash terminal ) and an M before it indicating the it has been merged

This is not what the M signifies. The Mtabfilename output from git checkout means: I did the checkout as instructed, but there's a file here that was never checked in. Here's the name(s) of these file(s). I've kept them unchanged from the state they had in the previous checkout.

If you meant to add and commit that file while you were working on branchname2, simply run git checkout branchname2 again, use git diff and/or git diff --cached and/or git status to see what's going on, use git add if you like, and so on. Once this uncommitted work is either saved properly, or erased because it was inappropriate—whatever you like, you can do here—you can then safely git checkout branchname1 again, this time without carrying over unsaved work.

Additional options

If you need to do work in more than one branch at a time, without committing it, there are some ways to do that. In particular:

  • You can make more than one clone. Each clone is a full copy of everything as usual, plus a work area (your working tree or work-tree) where you can do work, plus Git's index aka staging area.

  • You can use git worktree add. This command was new in Git 2.5 (and had some important fixes in Git 2.15), so you'll need an up-to-date Git version; some systems still hand out Git 1.7 or 1.8 (!). This lets you use a single underlying repository, but have multiple working trees. Each working tree comes with a private Git index-aka-staging-area.

Git is a big and complicated piece of software, with a steep learning curve—if you try to take it in as an S-curve, it's pretty frustrating. Give yourself time.

torek
  • 448,244
  • 59
  • 642
  • 775