Sei sulla pagina 1di 46

GIT overview

Table of Contents
GIT overview----------------------------------------------------------------------------------------------1
1.

What is GIT?--------------------------------------------------------------------------------------------4
1.1

Snapshots, not differences-------------------------------------------------------------------4

1.2

DVCS Terminologies----------------------------------------------------------------------------5

2.

Install GIT-----------------------------------------------------------------------------------------------7

3.

Setting up the repository---------------------------------------------------------------------------7

4.

5.

3.1

git config-------------------------------------------------------------------------------------------7

3.2

git clone--------------------------------------------------------------------------------------------8

Using Branches----------------------------------------------------------------------------------------9
4.1

git branch------------------------------------------------------------------------------------------9

4.2

git checkout-------------------------------------------------------------------------------------11

Git operations----------------------------------------------------------------------------------------12
5.1

Saving changes--------------------------------------------------------------------------------12

5.1.1

git add---------------------------------------------------------------------------------------12

5.1.2

git commit----------------------------------------------------------------------------------12

5.2

Inspecting a repository----------------------------------------------------------------------14

5.2.1

git status-----------------------------------------------------------------------------------14

5.2.2

git log----------------------------------------------------------------------------------------14

5.3

Undoing changes------------------------------------------------------------------------------15

5.3.1

git checkout-------------------------------------------------------------------------------15

5.3.2

git revert------------------------------------------------------------------------------------16

5.3.3

git reset-------------------------------------------------------------------------------------17

5.3.4

git clean-------------------------------------------------------------------------------------20

5.4

Syncing-------------------------------------------------------------------------------------------20

5.4.1

git remote----------------------------------------------------------------------------------21

5.4.2

git fetch-------------------------------------------------------------------------------------22

5.4.3

git pull---------------------------------------------------------------------------------------22

5.4.4

git push-------------------------------------------------------------------------------------24

5.4.5

git merge-----------------------------------------------------------------------------------26
1

5.4.6

git rebase-----------------------------------------------------------------------------------28

5.4.7

Rebase vs Merge-------------------------------------------------------------------------30

5.4.8

Resolving merge conflicts-------------------------------------------------------------33

6.

Git commands at a glance-----------------------------------------------------------------------34

7.

Collaborating Making Pull request-----------------------------------------------------------37

8.

Branching Model------------------------------------------------------------------------------------40

9.

References--------------------------------------------------------------------------------------------43

Document Revision Table:


Name

Changes

Versio
2

n#
Neha Arora

Initial Version

1.0

1. What is GIT?
Git is an open source Distributed Version Control System.

In Centralized Version Control Systems like SVN, each developer gets a working
copy that points back to a single central repository. Git, however, is a distributed
version control system. Instead of a working copy, each developer gets their own
local repository, complete with a full history of commits. Having a full local history
makes Git fast, since it means you dont need a network connection to create
commits, inspect previous versions of a file, or perform diffs between commits.
Distributed development also makes it easier to scale your engineering team. If
someone breaks the production branch in SVN, other developers cant check in their
changes until its fixed. With Git, this kind of blocking doesnt exist. Everybody can
continue going about their business in their own local repositories.

1.1

Snapshots, not differences

The major difference between Git and any other VCS (Subversion and friends
included) is the way Git thinks about its data.
Whereas SVN tracks differences of a file, Gits version control model is based on
snapshots. For example, an SVN commit consists of a diff compared to the original
file added to the repository. Git, on the other hand, records the entire contents of
each file in every commit.
Git stores data in a file system made up of snapshots. Each time you save a
changed version of your project called commit Git creates a snapshot of the

file and stores a reference to it. If the file has not changed, Git only stores a
reference to the already-stored identical version of it.

SVN differences

GIT snapshots

1.2

DVCS Terminologies

Local Repository(.git directory)


Every VCS tool provides a private workplace as a working copy. Developers make
changes in their private workplace and after commit, these changes become a part
of the repository. Git takes it one step further by providing them a private copy of
the whole repository. Users can perform many operations with this repository such
as add file, remove file, rename file, move file, commit changes, and many more.
Working Directory and Staging Area
The working directory is the place where files are checked out. In other CVCS,
developers generally make modifications and commit their changes directly to the
repository. But Git uses a different strategy. Git doesnt track each and every
modified file. Whenever you do commit an operation, Git looks for the files present
in the staging area. Only those files present in the staging area are considered for
commit and not all the modified files.

The basic Git workflow goes something like this:


1. You modify files in your working directory.
2. You stage the files, adding snapshots of them to your staging area.
3. You do a commit, which takes the files that are in the staging area and stores
that snapshot permanently to your local Git directory.

File States
Files in Git can reside in three main states: committed, modified and staged.
Modified - File has been changed but not committed (file in working directory)
Staged - Flagged a files changed version to be committed in the next snapshot (file
in staging area)
Committed - Data is securely stored in a local git repository (file in local repository)
All files in a checked out (or working) copy of a project file are either in a tracked or
untracked state.
Tracked - Tracked files can be modified, unmodified, or staged; they were part of
the most recent file snapshot.
Untracked - Untracked files were not in the last snapshot and do not currently
reside in the staging area. These may be the files that have just been added to the
project.
Branches
Branches are used to create another line of development. By default, Git has a
master branch. Usually, a branch is created to work on a new feature. Once the
feature is completed, it is merged back with the master branch. Every branch is
referenced by HEAD, which points to the latest commit in the branch. Whenever
you make a commit, HEAD is updated with the latest commit.
HEAD
HEAD is a pointer, which always points to the latest commit in the branch.
Whenever you make a commit, HEAD is updated with the latest commit. The heads
of the branches are stored in .git/refs/heads/ directory.

2. Install GIT
a. Install the latest version of GIT for your OS.
You can download Git by visiting this link and following the posted directions:
https://git-scm.com/download
b. Open a Command Prompt (or Git Bash if during installation you elected not to
use Git from the Windows Command Prompt).
c. Verify the installation was successful by typing git --version:
$ git version
$ git version 2.9.2

3. Setting up the repository


3.1

git config

The git config command lets you configure your Git installation (or an individual
repository) from the command line. This command can define everything from
user info to preferences to the behavior of a repository.
Run the following commands to configure your Git username and email using the
following commands, replacing Emma's name with your own. These details will
be associated with any commits that you create:
$ git config --global user.name "Emma Paris"
$ git config --global user.email "eparis@atlassian.com"
If you want to check your settings, you can use the git config --list command to
list all the settings Git can find at that point:
$ git config --list
user.name=John Doe
user.email=johndoe@example.com
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto
...

3.2

git clone

The git clone command copies an existing Git repository. This is sort of like svn
checkout, except the working copy is a full-fledged Git repositoryit has its
own history, manages its own files, and is a completely isolated environment
from the original repository.
As a convenience, cloning automatically creates a remote connection called
origin pointing back to the original repository. This makes it very easy to
interact with a central repository.
git clone <repo url> <directory>
Clone the repository located at <repo url> into the folder called <directory> on
the local machine.
OR
1. Navigate to the repository in Bitbucket.

2. Click the Clone button.


3. Copy the clone command (either the SSH format or the HTTPS).
(If you are using the SSH protocol, ensure your public key is in Bitbucket and
loaded on the local system to which you are cloning.)
4. Launch a terminal window.
5. Change to the local directory where you want to clone your repository.
6. Paste the command you copied from Bitbucket, for example:
git clone ssh://git@bitbucket.example.com:7999/PROJ/repo.git

4. Using Branches

4.1

git branch

A branch represents an independent line of development. Branches serve as an


abstraction for the edit/stage/commit process .You can think of them as a way to
request a brand new working directory, staging area, and project history. New
commits are recorded in the history for the current branch, which results in a fork in
the history of the project.
The git branch command lets you create, list, rename, and delete branches. It
doesnt let you switch between branches or put a forked history back together
again. For this reason, git branch is tightly integrated with the git checkout and git
merge commands.
Usage:
git branch
List all of the branches in your repository.
9

git branch <branch>


Create a new branch called <branch>. This does not check out the new branch.
git branch -d <branch>
Delete the specified branch. This is a safe operation in that Git prevents you from
deleting the branch if it has unmerged changes.
git branch -D <branch>
Force delete the specified branch, even if it has unmerged changes. This is the
command to use if you want to permanently throw away all of the commits
associated with a particular line of development.
git branch -m <branch>
Rename the current branch to <branch>.
In Git, branches are a part of your everyday development process. When you want
to add a new feature or fix a bugno matter how big or how smallyou spawn a
new branch to encapsulate your changes. This makes sure that unstable code is
never committed to the main code base, and it gives you the chance to clean up
your features history before merging it into the main branch.

For example, the diagram above visualizes a repository with two isolated lines of
development, one for a little feature, and one for a longer-running feature. By
developing them in branches, its not only possible to work on both of them in
parallel, but it also keeps the main master branch free from questionable code.
Branch Tips
The implementation behind Git branches is much more lightweight than SVNs
model. Instead of copying files from directory to directory, Git stores a branch as a
10

reference to a commit. In this sense, a branch represents the tip of a series of


commitsit's not a container for commits. The history for a branch is extrapolated
through the commit relationships.
This has a dramatic impact on Git's merging model. Whereas merges in SVN are
done on a file-basis, Git lets you work on the more abstract level of commits. You
can actually see merges in the project history as a joining of two independent
commit histories.
Example - Creating Branches
It's important to understand that branches are just pointers to commits. When you
create a branch, all Git needs to do is create a new pointerit doesnt change the
repository in any other way. So, if you start with a repository that looks like this:

Then, you create a branch using the following command:


git branch crazy-experiment

The repository history remains unchanged. All you get is a new pointer to the
current commit:
Note that this only creates the new branch. To start adding commits to it, you need
to select it with git checkout, and then use the standard git add and git commit
commands.

11

4.2

git checkout

The git checkout command lets you navigate between the branches created by git
branch. Checking out a branch updates the files in the working directory to match
the version stored in that branch, and it tells Git to record all new commits on that
branch. Think of it as a way to select which line of development youre working on.
Usage:
git checkout <existing-branch>
Check out the specified branch, which should have already been created with git
branch. This makes <existing-branch> the current branch, and updates the working
directory to match.
git checkout -b <new-branch>
Creates and check out <new-branch>. The -b option is a convenience flag that tells
Git to run git branch <new-branch> before running git checkout <new-branch>.

5. Git operations
5.1

Saving changes

5.1.1 git add


The git add command adds a change in the working directory to the staging area. It
tells Git that you want to include updates to a particular file in the next commit.
However, git add doesn't really affect the repository in any significant way
changes are not actually recorded until you run git commit.

12

Usage:
git add <file>
Stage all changes in <file> for the next commit.
git add <directory>
Stage all changes in <directory> for the next commit.
git add *
Stage all modified files for the next commit.
The git add command should not be confused with svn add, which adds a file to the
repository. Instead, git add works on the more abstract level of changes. This means
that git add needs to be called every time you alter a file, whereas svn add only
needs to be called once for each file.
git add adds the modified file to the staging area
5.1.2 git commit
The git commit command commits the staged snapshot to the project history.
Committed snapshots can be thought of as safe versions of a projectGit will
never change them unless you explicitly ask it to.
While they share the same name, this command is nothing like svn commit.
Snapshots are committed to the local repository, and this requires absolutely no
interaction with other Git repositories.

13

Usage:
git commit
Commit the staged snapshot. This will launch a text editor prompting you for a
commit message. After youve entered a message, save the file and close the editor
to create the actual commit.
git commit m <message>
Commit the staged snapshot, but instead of launching a text editor, use
<message> as the commit message.
git commit commits the staged snapshot to the project history.
git commit --amend
The git commit --amend command is a convenient way to fix up the most recent
commit. It lets you combine staged changes with the previous commit instead of
committing it as an entirely new snapshot. It can also be used to simply edit the
previous commit message without changing its snapshot.
But, amending doesnt just alter the most recent commitit replaces it entirely. To
Git, it will look like a brand new commit.
git commit --amend
Combine the staged changes with the previous commit and replace the previous
commit with the resulting snapshot. Running this when there is nothing staged lets
you edit the previous commits message without altering its snapshot.

14

5.2

Inspecting a repository

5.2.1 git status


The git status command displays the state of the working directory and the staging
area. It lets you see which changes have been staged, which havent, and which
files arent being tracked by Git. Status output does not show you any information
regarding the committed project history.
Usage:
git status
List which files are staged, unstaged, and untracked.
Sample output showing the three main categories of a git status call is included
below:
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
#modified: hello.py
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working
directory)
#
#modified: main.py
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
#hello.pyc

5.2.2 git log


The git log command displays committed snapshots. It lets you list the project
history, filter it, and search for specific changes. While git status lets you inspect the
working directory and the staging area, git log only operates on the committed
history.

15

Usage:
git log
Display the entire commit history using the default formatting.
git log n <limit>
Limit the number of commits by <limit>. For example, git log -n 3 will display only 3
commits.
git log <file>
Only display commits that include the specified file. This is an easy way to see the
history of a particular file.

5.3

Undoing changes

5.3.1 git checkout


The git checkout command serves three distinct functions: checking out files,
checking out commits, and checking out branches. In this module, were only
concerned with the first two configurations. The third configuration is already
discussed in module 4.2
Checking out a commit makes the entire working directory match that commit. This
can be used to view an old state of your project without altering your current state
in any way. Checking out a file lets you see an old version of that particular file,
leaving the rest of your working directory untouched.
Usage:
git checkout <commit> <file>

16

Check out a previous version of a file. This turns the <file> that resides in the
working directory into an exact copy of the one from <commit> and adds it to the
staging area.

git checkout <commit>


Update all files in the working directory to match the specified commit. You can use
either a commit hash or a tag as the <commit> argument. This will put you in a
detached HEAD state.
For example, if you only wanted to see the hello.jsp file from the old commit, you
could use the following command:
git checkout a1e8fb5 hello.jsp
Remember, unlike checking out a commit, this does affect the current state of your
project. The old file revision will show up as a Change to be committed, giving you
the opportunity to revert back to the previous version of the file. If you decide you
dont want to keep the old version, you can check out the most recent version with
the following:
git checkout HEAD hello.jsp
5.3.2 git revert
The git revert command undoes a committed snapshot. But, instead of removing
the commit from the project history, it figures out how to undo the changes
introduced by the commit and appends a new commit with the resulting content.
This prevents Git from losing history, which is important for the integrity of your
revision history and for reliable collaboration.

Usage:
git revert <commit>
Generate a new commit that undoes all of the changes introduced in <commit>,
then apply it to the current branch.
17

Reverting vs. Resetting


It's important to understand that git revert undoes a single commitit does not
revert back to the previous state of a project by removing all subsequent
commits. In Git, this is actually called a reset, not a revert.

Reverting has two important advantages over resetting. First, it doesnt change the
project history, which makes it a safe operation for commits that have already
been published to a shared repository.
Second, git revert is able to target an individual commit at an arbitrary point in the
history, whereas git reset can only work backwards from the current commit. For
example, if you wanted to undo an old commit with git reset, you would have to
remove all of the commits that occurred after the target commit, remove it, then recommit all of the subsequent commits. Needless to say, this is not an elegant undo
solution.
5.3.3 git reset
When you undo with git reset, there is no way to retrieve the original copyit is a
permanent undo. Care must be taken when using this tool, as its one of the only Git
commands that has the potential to lose your work.
Like git checkout, git reset is a versatile command with many configurations. It can
be used to remove committed snapshots, although its more often used to undo
changes in the staging area and the working directory. In either case, it should only
be used to undo local changesyou should never reset snapshots that have been
shared with other developers.

18

Usage:
git reset <file>
Remove the specified file from the staging area, but leave the working directory
unchanged. This unstages a file without overwriting any changes.
git reset
Reset the staging area to match the most recent commit, but leave the working
directory unchanged. This unstages all files without overwriting any changes, giving
you the opportunity to re-build the staged snapshot from scratch.
git reset --hard
Reset the staging area and the working directory to match the most recent commit.
In addition to unstaging changes, the --hard flag tells Git to overwrite all changes in
the working directory, too. Put another way: this obliterates all uncommitted
changes, so make sure you really want to throw away your local developments
before using it.
git reset <commit>
Move the current branch tip backward to <commit>, reset the staging area to
match, but leave the working directory alone. All changes made since <commit>

19

will reside in the working directory, which lets you re-commit the project history
using cleaner, more atomic snapshots.
git reset --hard <commit>
Move the current branch tip backward to <commit> and reset both the staging area
and the working directory to match. This obliterates not only the uncommitted
changes, but all commits after <commit>, as well.
Examples
Unstaging a File
The git reset command is frequently encountered while preparing the staged
snapshot. The next example assumes you have two files called hello.py and main.py
that youve already added to the repository.
# Edit both hello.py and main.py
# Stage everything in the current directory
git add .
# Realize that the changes in hello.py and main.py
# should be committed in different snapshots
# Unstage main.py
git reset main.py
# Commit only hello.py
git commit -m "Make some changes to hello.py"
# Commit main.py in a separate snapshot
git add main.py
git commit -m "Edit main.py"
As you can see, git reset helps you keep your commits highly-focused by letting you
unstage changes that arent related to the next commit.
Removing Local Commits
The next example shows a more advanced use case. It demonstrates what happens
when youve been working on a new experiment for a while, but decide to
completely throw it away after committing a few snapshots.
# Create a new file called `foo.py` and add some code to it
# Commit it to the project history
git add foo.py
git commit -m "Start developing a crazy feature"

20

# Edit `foo.py` again and change some other tracked files, too
# Commit another snapshot
git commit -a -m "Continue my crazy feature"
# Decide to scrap the feature and remove the associated commits
git reset --hard HEAD~2
The git reset HEAD~2 command moves the current branch backward by two
commits, effectively removing the two snapshots we just created from the project
history. Remember that this kind of reset should only be used on unpublished
commits. Never perform the above operation if youve already pushed your
commits to a shared repository.
5.3.4 git clean
The git clean command removes untracked files from your working directory. This is
really more of a convenience command, since its trivial to see which files are
untracked with git status and remove them manually. git clean is not undoable,
so make sure you really want to delete the untracked files before you run it.
The git clean command is often executed in conjunction with git reset --hard.
Remember that resetting only affects tracked files, so a separate command is
required for cleaning up untracked ones. Combined, these two commands let you
return the working directory to the exact state of a particular commit.
Usage:
git clean -n
Perform a dry run of git clean. This will show you which files are going to be
removed without actually doing it.
git clean -f
Remove untracked files from the current directory.
git clean -df
Remove untracked files and untracked directories from the current directory.

5.4

Syncing

SVN uses a single central repository to serve as the communication hub for
developers, and collaboration takes place by passing change sets between the
developers working copies and the central repository. This is different from Gits
collaboration model, which gives every developer their own copy of the repository,
complete with its own local history and branch structure. Users typically need to
share a series of commits rather than a single change set. Instead of committing a
21

change set from a working copy to the central repository, Git lets you share entire
branches between repositories.
The commands presented below let you manage connections with other
repositories, publish local history by pushing branches to other repositories, and
see what others have contributed by pulling branches into your local repository.
5.4.1 git remote
The git remote command lets you create, view, and delete connections to other
repositories. Remote connections are more like bookmarks rather than direct links
into other repositories. Instead of providing real-time access to another repository,
they serve as convenient names that can be used to reference a not-so-convenient
URL.
For example, the following diagram shows two remote connections from your repo
into the central repo and another developers repo. Instead of referencing them by
their full URLs, you can pass the origin and john shortcuts to other Git commands.

Usage:
git remote -v
List the remote connections you have to other repositories and include the URL of
each connection.
git remote add <name> <url>
Create a new connection to a remote repository. After adding a remote, youll be
able to use <name> as a convenient shortcut for <url> in other Git commands.
git remote rm <name>
Remove the connection to the remote repository called <name>.
22

The origin Remote


When you clone a repository with git clone, it automatically creates a remote
connection called origin pointing back to the cloned repository. This is useful for
developers creating a local copy of a central repository, since it provides an easy
way to pull upstream changes or publish local commits. This behavior is also why
most Git-based projects call their central repository origin.
5.4.2 git fetch
The git fetch command imports commits from a remote repository into your local
repo. The resulting commits are stored as remote branches instead of the normal
local branches that weve been working with. This gives you a chance to review
changes before integrating them into your copy of the project.
Usage:
git fetch <remote>
Fetch all of the branches from the repository. This also downloads all of the required
commits and files from the other repository.
git fetch <remote> <branch>
Same as the above command, but only fetch the specified branch.
So, unlike SVN, synchronizing your local repository with a remote repository is
actually a two-step process: fetch, then merge. The git pull command is a
convenient shortcut for this process.
5.4.3 git pull
Merging upstream changes into your local repository is a common task in Git-based
collaboration workflows. We can do this with git fetch followed by git merge, but git
pull rolls this into a single command.

23

Usage:
git pull <remote>
Fetch the specified remotes copy of the current branch and immediately merge it
into the local copy. This is the same as git fetch <remote> followed by git merge
origin/<current-branch>.
You can think of git pull as Git's version of svn update. Its an easy way to
synchronize your local repository with upstream changes. The following diagram
explains each step of the pulling process.
You start out thinking your repository is synchronized, but then git fetch reveals that
origin's version of master has progressed since you last checked it. Then git merge
immediately integrates the remote master into the local one.

24

5.4.4 git push


Pushing is how you transfer
commits from your local repository
to a remote repo. It's the counterpart to git fetch, but whereas fetching imports
commits to local branches, pushing exports commits to remote branches.

Usage:
git push <remote> <branch>

25

Push the specified branch to <remote>, along with all of the necessary commits
and internal objects. This creates a local branch in the destination repository. To
prevent you from overwriting commits, Git wont let you push when it results in a
non-fast-forward merge in the destination repository.
The most common use case for git push is to publish your local changes to a central
repository. After youve accumulated several local commits and are ready to share
them with the rest of the team, you (optionally) clean them up with an interactive
rebase, then push them to the central repository.

The above diagram shows what happens when your local master has progressed
past the central repositorys master and you publish changes by running git push
origin master.

26

5.4.5 git merge


Merging is Git's way of putting a forked history back together again. The git merge
command lets you take the independent lines of development created by git
branch and integrate them into a single branch.
Note that all of the commands presented below merge into the current branch. The
current branch will be updated to reflect the merge, but the target branch will be
completely unaffected. Again, this means that git merge is often used in
conjunction with git checkout for selecting the current branch.
Usage:
git merge <branch>
Merge the specified branch into the current branch.
Once youve finished developing a feature in an isolated branch, it's important to be
able to get it back into the main code base. Depending on the structure of your
repository, Git has several distinct algorithms to accomplish this: a fast-forward
merge or a 3-way merge.
Fast-forward merge
A fast-forward merge can occur when there is a linear path from the current branch
tip to the target branch. Instead of actually merging the branches, all Git has to
do to integrate the histories is move (i.e., fast forward) the current branch tip up
to the target branch tip. This effectively combines the histories, since all of the
commits reachable from the target branch are now available through the current
one. For example, a fast forward merge of some-feature into master would look
something like the following:

27

However, a fast-forward merge is not possible if the branches have diverged. When
there is not a linear path to the target branch, Git has no choice but to combine
them via a 3-way merge.
3-way merge
3-way merges use a dedicated commit to tie together the two histories. The
nomenclature comes from the fact that Git uses three commits to generate the
merge commit: the two branch tips and their common ancestor.

28

No Fast-forward merge
git merge --no-ff <branch>
When you use the git merge --no-ff <branch> command, instead of a branch
simply moving its pointer forward, a new commit object is created. The no-ff flag is
often used to prevent the loss of historical information regarding a merged-in
branch. So it will always generate a merge commit for documenting merges in the
repository.
5.4.6 git rebase
Rebasing is the process of moving a branch to a new base commit. The general
process can be visualized as the following:

29

From a content perspective, rebasing really is just moving a branch from one
commit to another. But internally, Git accomplishes this by creating new commits
and applying them to the specified baseits literally rewriting your project history.
Its very important to understand that, even though the branch looks the same, its
composed of entirely new commits.
Usage:
git rebase <base>
Rebase the current branch onto <base>, which can be any kind of commit
reference (an ID, a branch name, a tag, or a relative reference to HEAD).
git rebase i
Running git rebase with the -i flag begins an interactive rebasing session. Instead of
blindly moving all of the commits to the new base, interactive rebasing gives you
the opportunity to alter individual commits in the process. This lets you clean up
history by removing, splitting, and altering an existing series of commits.
Usage:
git rebase i <base>

30

Rebase the current branch onto <base>, but use an interactive rebasing session.
This opens an editor where you can enter commands (described below) for each
commit to be rebased. These commands determine how individual commits will be
transferred to the new base. You can also reorder the commit listing to change the
order of the commits themselves.
5.4.7 Rebase vs Merge
Consider what happens when you start working on a new feature in a dedicated
branch, then another team member updates the master branch with new commits.
This results in a forked history, which should be familiar to anyone who has used Git
as a collaboration tool.
Now, lets say that the new commits in master are relevant to the feature that
youre working on. To incorporate the new commits into your feature branch, you
have two options: merging or rebasing.

The Merge Option


The easiest option is to merge the master branch into the feature branch using
something like the following:
git checkout feature
git merge master

31

This creates a new merge commit in the feature branch that ties together the
histories of both branches, giving you a branch structure that looks like this:

Merging is nice because its a non-destructive operation. The existing branches are
not changed in any way. This avoids all of the potential pitfalls of rebasing
(discussed below).
The Rebase Option
As an alternative to merging, you can rebase the feature branch onto master branch
using the following commands:
git checkout feature
git rebase master
This moves the entire feature branch to begin on the tip of the master branch,
effectively incorporating all of the new commits in master. But, instead of using a
merge commit, rebasing re-writes the project history by creating brand new
commits for each commit in the original branch.

32

The major benefit of rebasing is that you get a much cleaner project history. First, it
eliminates the unnecessary merge commits required by git merge. Second, as you
can see in the above diagram, rebasing also results in a perfectly linear project
historyyou can follow the tip of feature all the way to the beginning of the project
without any forks. This makes it easier to navigate your project with commands like
git log.
But, there are two trade-offs for this pristine commit history: safety and traceability.
Re-writing project history can be potentially catastrophic for your collaboration
workflow. And, less importantly, rebasing loses the context provided by a merge
commityou cant see when upstream changes were incorporated into the feature.
Finally, you can do a fast-forward merge to integrate the polished feature branch
into the main code base:
git checkout master
git merge feature

33

5.4.8 Resolving merge conflicts


If the two branches youre trying to merge both changed the same part of the same
file, Git wont be able to figure out which version to use. When such a situation
occurs, it stops right before the merge commit so that you can resolve the conflicts
manually.
The great part of Git's merging process is that it uses the familiar edit/stage/commit
workflow to resolve merge conflicts. When you encounter a merge conflict, running
the git status command shows you which files need to be resolved. For example,
if both branches modified the same section of hello.py, you would see something
like the following:
#
#
#
#
#

On branch master
Unmerged paths:
(use "git add/rm ..." as appropriate to mark resolution)
both modified: hello.py

#
Then, you can go in and fix up the merge to your liking. When you're ready to finish
the merge, all you have to do is run git add on the conflicted file(s) to tell Git
they're resolved. Then, you run a normal git commit to generate the merge
commit. Its the exact same process as committing an ordinary snapshot, which
means its easy for normal developers to manage their own merges.
34

Note that merge conflicts will only occur in the event of a 3-way merge. Its not
possible to have conflicting changes in a fast-forward merge.

6. Git commands at a glance

35

Git task
Tell Git who
you are

Notes

Git commands

Configure the author name and


email address to be used with
your commits.Note that Git strips
some characters (for example
trailing periods) from user.name.

Create a
new local
repository

git config global user.name Sam


Smith
git config global user.email
sam@example.com

git init

Create a working copy of a local


repository:

git clone /path/to/repository

For a remote server, use:

git clone
username@host:/path/to/repository

Add files

Add one or more files to staging


(index):

git add <filename>git add *

Commit

Commit changes to head (but not


yet to the remote repository):

git commit -m Commit message

Commit any files youve added


with git add, and also commit any
files youve changed since then:

git commit -a

Push

Send changes to the master


branch of your remote repository:

git push origin master

Status

List the files you've changed and


those you still need to add or
commit:

git status

Check out a
repository

Connect to a If you haven't connected your


remote
local repository to a remote
repository
server, add the server to be able
to push to it:

Branches

git remote add origin <server>

List all currently configured


remote repositories:

git remote -v

Create a new branch and switch


to it:

git checkout -b <branchname>

Switch from one branch to


another:

git checkout <branchname>

List all the branches in your repo,


and also tell you what branch
you're currently in:

git branch

36

37

7. Collaborating Making Pull request


Pull requests are a feature that makes it easier for developers to collaborate using
Bitbucket. It provides a user-friendly web interface for discussing proposed changes
before integrating them into the official project.
Pull requests are a mechanism for a developer to notify team members that they
have completed a feature. Once their feature branch is ready, the developer files a
pull request via their Bitbucket account. This lets everybody involved know that
they need to review the code and merge it into the specified target branch.

But, the pull request is more than just a notificationits a dedicated forum for
discussing the proposed feature. If there are any problems with the changes,
teammates can post feedback in the pull request and even tweak the feature by
pushing follow-up commits. All of this activity is tracked directly inside of the pull
request.

38

When you file a pull request, all youre doing is requesting that another developer
(e.g., the project maintainer) pulls a branch from your repository into their
repository. This means that you need to provide 4 pieces of information to file a pull
request: the source repository, the source branch, the destination repository, and
the destination branch. Many of these values will be set to a sensible default by
Bitbucket.

39

General process is as follows:


1. A developer creates the feature in a dedicated branch in their local repo.

40

2. The developer pushes the branch to a public Bitbucket repository.


3. The developer files a pull request via Bitbucket when a feature, release,
bugfix or hotfix branch needs to be reviewed.
4. The rest of the team reviews the code, discusses it, and alters it.
5. a. If the reviewer thinks the feature is ready to merge into the selected target
branch, all he has to do is hit the Merge button to approve the pull request
and merge developers feature into the target branch.
b. But if the reviewer founds a small bug and needs the developer to fix it
before merge - he can either post a comment to the pull request as a whole,
or he can select a specific commit in the features history to comment on.

41

c. To correct the error, developer adds another commit to his feature branch
and pushes it to the Bitbucket repository, just like he did the first time
around. This commit is automatically added to the original pull request, and
reviewer can review the changes again, right next to his original comment. If
all is set, reviewer accepts the changes, merges the feature branch into
target branch, and closes the pull request.
6. The feature is now integrated into the project, and any other developers
working on it can pull it into their own local repositories using the standard git
pull command.

8. Branching Model

42

The main branches


At the core, the development model is greatly inspired by existing models out there.
The central repo holds two main branches with an infinite lifetime:
master
develop
43

The master branch at origin should be familiar to every Git user. Parallel to the
master branch, another branch exists called develop.
We consider origin/master to be the main branch where the source code of HEAD
always reflects a production-ready state.
We consider origin/develop to be the main branch where the source code of HEAD
always reflects a state with the latest delivered development changes for the next
release.
In our case, after migration; the develop will reflect the state of SVN trunk.
When the source code in the develop branch reaches a stable point and is ready to
be released, all of the changes should be merged back into master somehow and
then tagged with a release number.

The supporting branches


Next to the main branches - master and develop, our development model uses a
variety of supporting branches to aid parallel development between team members,
ease tracking of features, prepare for production releases and to assist in quickly
fixing live production problems. Unlike the main branches, these branches always
have a limited life time, since they might be removed eventually.
The different types of branches we may use are:

Feature branches

Release branches

Hotfix branches

Bugfix branches
Each of these branches has a specific purpose and is bound to strict rules as to
which branches may be their originating branch and which branches must be their
merge targets.
Feature branches
May branch off from:
develop
Must merge back into:
develop
Feature branches are used to develop new features for the upcoming or a distant
future release. When starting development of a feature, the target release in which
this feature will be incorporated may well be unknown at that point. The essence of
a feature branch is that it exists as long as the feature is in development, but will
eventually be merged back into develop (to definitely add the new feature to the
upcoming release) or discarded (in case of a disappointing experiment). Feature
branches typically exist in developer repos only, not in origin.
44

**In our case, since there is a parallel development of features for different releases,
Feature branches corresponding to the upcoming release will only be merged to
develop.
Release branches
May branch off from:
develop
Must merge back into:
develop and master
Release branches support preparation of a new production release. They allow for
last-minute dotting of is and crossing ts. Furthermore, they allow for minor bug
fixes and preparing meta-data for a release (version number, build dates, etc.). By
doing all of this work on a release branch, the develop branch is cleared to receive
features for the next big release.
The key moment to branch off a new release branch from develop is when develop
(almost) reflects the desired state of the new release. At least all features that are
targeted for the release-to-be-built must be merged in to develop at this point in
time.
When the state of the release branch is ready to become a real release, some
actions need to be carried out. First, the release branch is merged into master
(since every commit on master is a new release by definition, remember). Next, that
commit on master must be tagged for easy future reference to this historical
version. Finally, the changes made on the release branch need to be merged back
into develop, so that future releases also contain these bug fixes.
Hotfix branches
May branch off from:
master
Must merge back into:
develop and master
Hotfix branches are very much like release branches in that they are also meant to
prepare for a new production release, albeit unplanned. They arise from the
necessity to act immediately upon an undesired state of a live production version.
When a critical bug in a production version must be resolved immediately, a hotfix
branch may be branched off from the corresponding tag that marks the production
version.
The essence is that work of team members (on the develop branch) can continue,
while another person is preparing a quick production fix.
45

When finished, the bugfix needs to be merged back into master, but also needs to
be merged back into develop, in order to safeguard that the bugfix is included in the
next release as well. This is completely similar to how release branches are finished.
**If hotfix is for the previous version of software that does not have an entry on the
master branch, then instead of merging it to the master, they are just tagged
separately.
Bugfix branches
May branch off from:
develop/release
Must merge back into:
develop/release
Bugfix branches are similar to feature branches expect they are used for fixing bugs
either in develop branch or release branch.

9. References
https://www.atlassian.com/git/
https://git-scm.com/book/en/v2/Getting-Started-Git-Basics

46

Potrebbero piacerti anche