Quantcast
Viewing all articles
Browse latest Browse all 29128

Git for Team Foundation Developers - Merging

This post will show how to merge using Git.  This is the third post in a series.

The series focuses on introducing Git for developers who are familiar with Team Foundation Version Control.

Background

One of the absolute coolest parts of Git is the flexibility it has with merging.  The types of scenarios it enables are exactly the scenarios that you face daily.  You make lots of check-ins, some of them you need to make (“Going on vacation… sorry if this breaks the build”), others you are happy to make (“Version 3 release… time for vacation”).  Git accommodates both.

Creating Branches

My previous post talked about branches in Git.  This is the thing I now most about Git, and also one of the things that completely tripped me up originally because I didn’t understand all the names that Git used.  When I create a team project in Visual Studio online, I clone the repository to a local repository.  I get the default branch, master.  I then create another branch, v2, and publish it to Visual Studio Online.  Here is what my branches look like right now:

Image may be NSFW.
Clik here to view.
image

What you don’t see in this picture is that there are actually 4 branches: 2 local, 2 remote.  VSOnline is the “origin” of the code, and each user has their own local repository.

Image may be NSFW.
Clik here to view.
image

The reason I bring this up in a discussion of merging is because you will see the term “ORIGIN” occasionally.  You can choose to create a branch from an existing branch in your local repository or the remote repository.

Our team decided to use the v2 branch for builds.  I first switch to the v2 branch (which switches in my local repository), and then I sync changes by clicking the Sync button, pulling changes from Visual Studio Online and pushing any outgoing commits.

Image may be NSFW.
Clik here to view.
image

Now that I know the local v2 and origin v2 repositories are synchronized, I am going to create a branch, kirke_v2, to do my work in.  The rest of my team may have branches specific to them, such as Simon_v2, Donovan_v2, and Paul_v2.  They are free to make whatever changes they want to their local branch, even publish that branch to the server, knowing that those changes are not part of the branch that our team is using for builds, the v2 branch.

Image may be NSFW.
Clik here to view.
image

Think about how powerful this is.  Rather than do all of your work against the central repository and possibly break the build, you can fetch the latest source from a particular branch on the server and work locally.  When you are ready to push your changes to the server, you do that explicitly.  I like that model.

Now that I’ve created the kirke_v2 branch, notice that it is local only and is not on the server.  We can tell that because it is an “unpublished branch”.

Image may be NSFW.
Clik here to view.
image

Finally, I decide to publish that branch to Visual Studio Online. 

Image may be NSFW.
Clik here to view.
image

There are now 6 total branches (3 local and 3 remote), and any changes that I make continue to work only against the local repository until I decide to push the changes to the remote repository.

Change Happens

Let’s cause a few changes.  Here is my project as I start:

Image may be NSFW.
Clik here to view.
image

I am going to add a few classes.  Here’s my base class.

Image may be NSFW.
Clik here to view.
image

I then implement a ConsoleOutputWriter and a DebugOutputWriter.

Image may be NSFW.
Clik here to view.
image

Each time I write some code, I commit.  You probably wouldn’t do this in your daily work, but I am doing it here to highlight how commits are tracked.

Studying History

Each time I added code, I made sure to commit.  You can see the history for the kirke_v2 branch in Visual Studio.  Go to Changes / Actions / View History.

Image may be NSFW.
Clik here to view.
image

The history for the branch is now shown.  Notice those two markers on the right.  Those show the pointers to the last commit in master that the branch kirke_v2 knows about, and the last commit in kirke_v2.

Image may be NSFW.
Clik here to view.
image

Let me explain that last part a little.  The pointer to master points to ffffb5c7, “Modified to use an interface”.  We’ll see in a second that the “master” branch actually has new commits in it.  When we branched from master to create “kirke_v2”, we copied all of the commits to the kirke_v2 branch.  This branch does not know anything yet of any changes in the master branch.  Think of it as a complete copy of all the commits from master, because that’s what it is.

Let’s go over to Git Bash.  We will run a program called “gitk”.

Image may be NSFW.
Clik here to view.
image

gitk opens, and we can see all of our checkins represented as a Directed Acyclic Graph (DAG).  I use this fancy word not to show off my incredibly vocabulary and sound as geeky as possible, but to point out that this term is used frequently in the Git documentation.  A directed acyclic graph is where you go from node to node and can never revisit a node.  For instance:

Image may be NSFW.
Clik here to view.
image

  1. The DAG shows all of the commits, with the most recent at top
  2. Each commit is by a user at a specific time
  3. Each commit has history that can be used to show the different between the current commit and the previous commit.

GitK is a fairly useful tool. 

Notice the changes that it is showing in section 3, highlighting new code in the Main method (using a green font).   

Managing Conflict

While I’ve been busy working on my fancy new class structure for writing output, a new intern in our group took the initiative to go make changes in Program.cs and commit them to the v2 branch. 

 Image may be NSFW.
Clik here to view.
image

Houston, we have a conflict.  That edit is smack-dab in the middle of the edits we made.  Let’s see how to handle this mess.  We don’t know that the intern did this yet, but we’ll soon discover it.  Let’s try to merge our changes from the kirke_v2 branch to the v2 branch.

Go to Team Explorer / Branches to view the branches, and then choose Merge.  The dialog will change to ask you to pick a source and destination.

Image may be NSFW.
Clik here to view.
image

Click the Merge button, and we start yelling at the intern.

Image may be NSFW.
Clik here to view.
image

Visual Studio is doing something incredibly nice for us here.  If you’re not familiar with Unix tools like vim, then editing this stuff using Git Bash is going to be very difficult.  Thankfully, the Visual Studio team provided a UI for this.  Click the “Resolve the conflicts” link.  The dialog changes to:

Image may be NSFW.
Clik here to view.
image

OK, that’s not very helpful.  Click the program.cs file in the Conflicts section.

Image may be NSFW.
Clik here to view.
image

That’s a little better.  Click that big “Merge” button.

Image may be NSFW.
Clik here to view.
image

Ah, there we go!  A visual diff tool that allows us to pick the changes from the conflicting commits.  Next to each conflict (highlighted in red in the tool) is a checkbox so that you can visually select which change stays.  The bottom pane shows the results.

Image may be NSFW.
Clik here to view.
image

Take that, intern.

Here’s the confusing part… what next?  The file has an asterisk next to its name, and its not a preview file it’s a file actually opened for editing.  Do I save it, or do I click that big “Merge” button on the right of the screen? 

Tucked away, somewhat hidden, is a button that says “Accept Merge”.

Image may be NSFW.
Clik here to view.
image

Click that, and now the Team Explorer pane changes to include a button that says “Commit Merge”.

Image may be NSFW.
Clik here to view.
image

Click the Commit Merge button.  Remember how we started this out trying to commit our changes?  Visual Studio says, “you’ve resolved all the problems, but we still haven’t done a commit.” 

Image may be NSFW.
Clik here to view.
image

Visualizing the DAG

Like I said in my previous posts, it helps to understand what Git is doing under the covers because the Visual Studio tools are nice enough to hide some of the gory details from us.  We already have gitk open, go to the File menu and choose “Start git gui”.

Image may be NSFW.
Clik here to view.
image

Once Git Gui starts, we can choose “Visualize All Branch History”.

Image may be NSFW.
Clik here to view.
image

Once that command runs, we can see the Directed Acyclic Graph for our commits.

Image may be NSFW.
Clik here to view.
image

The initial vertex in the graph is our initial check-in at the bottom.  We then move up to the point where we pushed our changes from the local repository to the remote repository.  Above that, we see a change on the v2 branch that the intern made.  We then see a few classes being added, to the kirke_v2 branch, and finally our kirke_v2 branch is merged with the main v2 branch. 

Developers typically branch and merge on a much more frequent basis than you would have using TFVC partially because you are working locally and have the luxury of doing this without concern of breaking the build.  You get the merge correct locally, and then you push to the remote repository.

Note: I’m impressed that I made it this far without really explaining the DAG and the various types in it.  My goal is to make you familiar and productive, not to mire you in theory.

For More Information

Use Git branches to switch contexts, suspend work, and isolate risk

Resolve Git conflicts

Image may be NSFW.
Clik here to view.

Viewing all articles
Browse latest Browse all 29128

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>