Forum: Ruby on Rails [OT] Git branch and merge

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
James B. (Guest)
on 2009-03-27 17:31
I have been using Git for about a year now, but always in the master
branch.  I decided to try working in a branch to get experience with
merging. Naturally enough, I am now observing some behaviour that I do
not understand.  I would appreciate any explanation of what is happening
and whether this is expected behaviour or not.

I initially pull from the remote repository and then checkout -b
workcopy from the master.  At this point workcopy and master are
identical.  In workcopy I modify x.rb and y.rb.  I then add/commit x.rb
in workcopy.  Next I checkout back to master.

From what i had read about git I believed that all the modifications
that I made to x and y in workcopy only affectedi workcopy; and that
those files in the master branch were still pristine as when they had
been pulled.  However, when I checkouted the master branch this is what
I saw:

$ git co master
M y.rb
Switched to branch master
$
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#
#       modified:   y.rb
no changes added to commit (use "git add" and/or "git commit -a")
$

A git diff on y.rb in both branches produced identical output. This
clearly indicates that the changes that I made in the working branch
affected the master branch too.  This is something that I thought not
possible.  Was I wrong in my belief or am I doing something wrong in my
implementation.

Further, I noted that x.rb had disappeared from view on the master even
though it had only been commited on the workcopy branch.  However, when
I ran merge on the master then I saw this:

$ git merge workcopy
Updating bb48bcc..339ec9a
y.rb: needs update
Fast forward

 ...x.rb                                            |    3 +
 1 file changed, 3 insertions(+), 0 deletions(-)
$

I am somewhat confused by this behaviour.  If what I do in a branch but
do not commit impacts the master while changes commited in the branch
simply disappear from view in the master then what is the advantage to
branching?  What am I doing wrong?
Milan D. (Guest)
on 2009-03-27 17:47
Well you didn't commit y.rb. If you wanna save not commited changes for
later use you should use stash.

p.s. I'm sorry if this gets sent twice it wouldn't let me submit because
the quote was too long. :)
Colin L. (Guest)
on 2009-03-27 17:49
(Received via mailing list)
2009/3/27 James B. <removed_email_address@domain.invalid>

> those files in the master branch were still pristine as when they had
> #   (use "git add <file>..." to update what will be committed)
> #
> #       modified:   y.rb
> no changes added to commit (use "git add" and/or "git commit -a")
> $


This is because you had not committed the change to y.rb. A checkout
will
not overwrite modified (uncommitted) files. You should have seen a
message
when you switched to the master warning that y was modified (M
filename).
You will think this is the optimum behaviour the when you forget to
commit
before a switch.


>
> A git diff on y.rb in both branches produced identical output. This
> clearly indicates that the changes that I made in the working branch
> affected the master branch too.  This is something that I thought not
> possible.  Was I wrong in my belief or am I doing something wrong in my
> implementation.


The master has not been affected, it is just the modified file left
there.


>
>
> Further, I noted that x.rb had disappeared from view on the master even
> though it had only been commited on the workcopy branch.  However, when
> I ran merge on the master then I saw this:
>

I do not understand how x.rb had disappeared from the master, you should
see
the original x.rb.  If x.rb was a new file on the branch then you would
expect it to be missing from the master.

Colin
Robert W. (Guest)
on 2009-03-27 17:50
James B. wrote:
> I have been using Git for about a year now, but always in the master
> branch.  I decided to try working in a branch to get experience with
> merging. Naturally enough, I am now observing some behaviour that I do
> not understand.  I would appreciate any explanation of what is happening
> and whether this is expected behaviour or not.
>
> I initially pull from the remote repository and then checkout -b
> workcopy from the master.  At this point workcopy and master are
> identical.  In workcopy I modify x.rb and y.rb.  I then add/commit x.rb
> in workcopy.  Next I checkout back to master.

But you didn't commit y.rb so the modifications still exist in your work
copy. (not your branch named workcopy, which would be very confusing to
me to name a branch that. I'd name it something like experimental or
after whatever feature I was working on).

> From what i had read about git I believed that all the modifications
> that I made to x and y in workcopy only affectedi workcopy; and that
> those files in the master branch were still pristine as when they had
> been pulled.  However, when I checkouted the master branch this is what
> I saw:

You misinterpreted what you read. The changes you make in a working copy
affect the working copy (i.e. the files you see when listing your
project files).

>
> $ git co master
> M y.rb
> Switched to branch master
> $
> $ git status
> # On branch master
> # Changed but not updated:
> #   (use "git add <file>..." to update what will be committed)
> #
> #       modified:   y.rb
> no changes added to commit (use "git add" and/or "git commit -a")
> $

Of course y.rb in your working copy shows the modification because you
modified it. You didn't commit it to your branch so git checkout of
master merges your working copy changes to what it gets from the master
branch effectively patching master's version of the file with your
working copy changes. This is expected and good behavior. You wouldn't
want git stomping on you local uncommitted changes.

I you have changes in your working copy when working on a branch and do
not want to commit those changes permanently, you can "stash" the
changes before checking out master. You do this using git stash command.
Typically, however, it makes sense to commit all your changes to the
branch before switch to another. After all, if it's an experimental
branch and you're at a reasonable time to switch away to something else
it's okay to just commit everything whether it's fully working or not.
It is an "experimental" branch after all.
James B. (Guest)
on 2009-03-27 18:19
Please bear with me as I walk through this:

I start with a pull from the remote.  I then create and checkout a
branch, say localtests.  I modify a file X.rb on localtests.  If I
switch back to the master via git checkout then the change to x.rb comes
with me into the master branch?  However, if I first commit the change
to x.rb on localtests then it does not?
Colin L. (Guest)
on 2009-03-27 18:43
(Received via mailing list)
2009/3/27 James B. <removed_email_address@domain.invalid>

>
> Please bear with me as I walk through this:
>
> I start with a pull from the remote.  I then create and checkout a
> branch, say localtests.  I modify a file X.rb on localtests.  If I
> switch back to the master via git checkout then the change to x.rb comes
> with me into the master branch?


It is not 'in' the master branch as it has not been committed, it is
just in
your working copy, which is the master branch plus your modified file.
If you want to get rid of modified files (so your working copy is the
same
as the current branch or master) you can use:
git checkout .
Note the dot on the end.  Be careful though, this will destroy any
uncommitted changes, do not get into the habit of doing it lightly or
you
will regret it at some point.


> However, if I first commit the change
> to x.rb on localtests then it does not?


If you commit it on the branch and switch to the master then the
modified
file is in the branch but the original is still in the master. You get
back
to the modified files by checking out the branch again.
James B. (Guest)
on 2009-03-27 19:04
I think that I may see where I went wrong.  Regardless of which named
branch I am on, git automatically puts any changes that I make into what
is effectively an anonymous working copy branch, where they remain until
they are added to a branch's future commit set.  Is this correct?
Colin L. (Guest)
on 2009-03-27 19:26
(Received via mailing list)
2009/3/27 James B. <removed_email_address@domain.invalid>

>
> I think that I may see where I went wrong.  Regardless of which named
> branch I am on, git automatically puts any changes that I make into what
> is effectively an anonymous working copy branch, where they remain until
> they are added to a branch's future commit set.  Is this correct?
> --


Not really, they are not on a branch, your working copy is just a set of
files in your folders.  When you switch branches git overwrites them
with
the version from the repository for that branch, unless they have been
modified but not committed, in which case it does not overwrite them.
The git repository contains all the versions of all the files on all the
branches and when you checkout it copies the appropriate versions into
your
local folders (but not overwriting modified files as we have seen).  A
commit copies files that you have modified and marked for commit into
the
repository (on the appropriate branch).

There are a number of good git tutorials on the web, google will find
them.
Perhaps looking at some of those would help to get the concepts sorted.
It
all seems a bit complex at first but once you have played with it for a
while you will wonder how life managed without it.
James B. (Guest)
on 2009-03-27 20:29
Colin L. wrote:

> There are a number of good git tutorials on the web, google will find
> them. Perhaps looking at some of those would help to get the concepts sorted.
> It all seems a bit complex at first but once you have played with it for a
> while you will wonder how life managed without it.

As I wrote, I have been using git for about a year now.  I converted all
our projects from Subversion last spring.  And I have done quite a few
tutorials.  I have no trouble in using git, I just now desire to see how
branch and merge works, without following a script so to speak.

> When you switch branches git overwrites them with the version
> from the repository for that branch, unless they have been
> modified but not committed, in which case it does not overwrite
> them.  The git repository contains all the versions of all the files
> on all the branches and when you checkout it copies the appropriate
> versions into your local folders (but not overwriting modified files
> as we have seen).  A commit copies files that you have modified and
> marked for commit into the repository (on the appropriate branch).

However, in addition to the forgoing, when I switched from a branch with
modified files into the master branch then git copied the modified files
into the master branch as well.  This put the master branch into a state
as if I had edited those files in that branch.  It was this behaviour
that confused me. I thought that whatever one did in a branch stayed in
that branch and did not follow one around modifying every other branch
that one enters.

How does one check for commits, and their contents, made to other
branches but not yet merged back into the master?
Robert W. (Guest)
on 2009-03-27 20:44
Colin L. wrote:
> Not really, they are not on a branch, your working copy is just a set of
> files in your folders.  When you switch branches git overwrites them
> with
> the version from the repository for that branch, unless they have been
> modified but not committed, in which case it does not overwrite them.

I'm not sure what version of git you're using, but I just did a sanity
check with a simple git repository. The version of git I'm using
(1.6.1.3) wouldn't let me switch to another branch with local changes to
the working directory. I had to use git checkout --merge master, which
then performed a 3-way merge between the versions on the branch, master
and working. In this case the file did conflict, as it should have,
After using git mergetool to resolve the conflicts then I was able to
commit the merged file into the master branch.

Note that in this case both the branch and master had versions of the
file committed previously.
James B. (Guest)
on 2009-03-27 20:53
Robert W. wrote:

>
> I'm not sure what version of git you're using, but I just did a sanity
> check with a simple git repository. The version of git I'm using
> (1.6.1.3) wouldn't let me switch to another branch with local changes to
> the working directory.

I am stuck with Git 1.5.5 on CentOS-5.3.  Unless and until some kind
soul adds a more recent version to EPEL.
Colin L. (Guest)
on 2009-03-27 22:41
(Received via mailing list)
2009/3/27 James B. <removed_email_address@domain.invalid>

> As I wrote, I have been using git for about a year now.  I converted all
> > as we have seen).  A commit copies files that you have modified and
> > marked for commit into the repository (on the appropriate branch).
>
> However, in addition to the forgoing, when I switched from a branch with
> modified files into the master branch then git copied the modified files
> into the master branch as well.


It is not copying the modified files anywhere, they are staying exactly
where they are,  the working copy is always in the same place (unless
you
move the whole tree of folders of course).


> This put the master branch into a state
> as if I had edited those files in that branch.  It was this behaviour
> that confused me. I thought that whatever one did in a branch stayed in
> that branch and did not follow one around modifying every other branch
> that one enters.


Again, the branch is not being modified, a branch is only modified when
a
commit or similar is performed. It is the working copy that you are
talking
about.


>
>
> How does one check for commits, and their contents, made to other
> branches but not yet merged back into the master?


I Use gitk
Colin L. (Guest)
on 2009-03-27 22:44
(Received via mailing list)
2009/3/27 Robert W. <removed_email_address@domain.invalid>

> (1.6.1.3) wouldn't let me switch to another branch with local changes to
> the working directory. I had to use git checkout --merge master, which
> then performed a 3-way merge between the versions on the branch, master
> and working. In this case the file did conflict, as it should have,
> After using git mergetool to resolve the conflicts then I was able to
> commit the merged file into the master branch.


I am using 1.5.6.3 on ubuntu.  I think the situation you are describing
may
be because the file has been modified on the master and branch.  I think
if
you make a new branch, checkout the branch, modify a file without
committing
(or staging) then checkout the master it will let you do it and leave
the
file modified
James B. (Guest)
on 2009-03-27 23:07
Colin L. wrote:

>
> I am using 1.5.6.3 on ubuntu.  I think the situation you are describing
> may be because the file has been modified on the master and branch.  I
> think  if you make a new branch, checkout the branch, modify a file
> without  committing (or staging) then checkout the master it will let
> you do it and leave  the file modified

This seems to be the case.  I built and installed Git-1.6.2-1 and I get
the same behaviour as I observed with 1.5.5.

$ git pull
...
$ git co -b newbranch
$ echo junk > README
$ git status
# On branch newbranch
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working
directory)
#
#       modified:   README
#
no changes added to commit (use "git add" and/or "git commit -a")
$
$ git co master
M       README
Switched to branch "master"
[byrnejb@inet04 proforma.git]$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working
directory)
#
#       modified:   README
#
no changes added to commit (use "git add" and/or "git commit -a")

I am still somewhat vague as to what is happening here but now at least
I know what to expect and that suffices.
Paul P. (Guest)
on 2009-03-29 08:23
It might help to think of your SVN experience.  In SVN when you checkout
a branch, you download a *copy* of the files in that branch in the repo.
When you commit, you upload your modified files to the branch in the
repository.

In Git,  although you have your version of repository in a database on
your computer, the situation is similar. In Git, when you checkout a
branch Git loads the files in that branch from the repo to the working
directory, where they show in your file system and you can open them and
modify them.  When you git commit them, the changes are written to the
repo.

In both Git & SVN, you generally make changes to your repository using
your vcs commands, and you make changes to the checked-out copy using
your editor.  In both cases, branches exist *in* the repository, and the
files that you are working on have come *from* the repository.  The
difference is that in Git the repo you are working from is your personal
version which is stored on your computer.
This topic is locked and can not be replied to.