Git with Bitbucket

Nihal Parmar
15 min readDec 14, 2022

Tutorial: Getting Started with Git and Bitbucket Fundamentals.

Git is the most widely used modern distributed version control system (VCS), a de facto standard in the industry. Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later. Git is a mature, actively maintained open-source project originally developed in 2005 by Linus Torvalds, the famous creator of the Linux operating system kernel. It allows you to revert selected files back to a previous state, revert the entire project back to a previous state, compare changes over time, see who last modified something that might be causing a problem, who introduced an issue and when, and more. Using a VCS also generally means that if you screw things up or lose files, you can easily recover them.

Bitbucket is a Git-based source code repository hosting service. It gives you a central place to manage git repositories (repos), collaborate on your source code, and guide you through the development flow. Bitbucket Cloud is hosted on Atlassian’s servers and accessed via a URL. Bitbucket Cloud has a built-in continuous integration tool, pipelines, that enables you to build, test and deploy from directly within Bitbucket.

Git Repository

Instead of using a single server-side repository to act as the ‘central’ codebase, every developer gets a server-side repository (this is known as forking). Each code contributor has not one, but two Git repositories: a private local one and a public server-side one. Some fun facts about repositories:

  • You have access to all files in your local repository, whether you are working on one file or multiple files.
  • You can view public repositories if you have a URL for that repository.
  • Each repository belongs to a user account or a team. In the case of a user account, that user owns the repository. In the case of a team, that team owns it.
  • The repository owner is the only person who can delete the repository.
  • A code project can consist of multiple repositories across multiple accounts but can also be a single repository from a single account.

Branching

A brunch 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 new working directory, staging area, and project history. New commits are recorded in history for the current branch, which results in a fork in the history of the project.

The main branch is the default development branch. Whenever you create a git repository, a branch named ‘main’ is created and becomes the active branch.

Branching capabilities is one of the biggest advantages of Git. Feature branches provide an isolated environment for every change to your codebase. When a developer wants to start working on something — no matter how big or small — they create a new branch. This ensures that the main branch always contains production-quality code. Using feature branches is much more reliable than directly editing production code.

There are a lot of different ways to use Git. There are the original command-line tools, and there are many graphical user interfaces of varying capabilities. In this article, we will be using Git on the command line.

Prerequisite:

  1. Install Git
  2. Create a free Bitbucket account

After creating your Bitbucket account, take a minute to explore the menu options:

The Your work dashboard displays the repositories and pull requests you care about. When you start working with the tool, you’ll see open pull requests that have you as a reviewer, open pull requests you’ve created, and the list of all repositories you can access.

The Repositories view lists all the repositories you can access.

Projects allow you to group and organize your repositories to make them easier to find. In the Projects view, you’ll see existing projects and you can create a new project. Clicking on a project displays all the repositories in that project.

Step 1. Create a repository

Initially, the repo you create in Bitbucket is going to be empty without any code in it. We’ll start adding files to it soon. The Bitbucket repo will be the central repository for your files and others can have access to your repository and the files it contains if you give them permission.

After creating a repository, you’ll copy a version to your local system — you can update it from one repo, then transfer those changes to the other.

Follow these steps to create a repository:

From Bitbucket, click Create and select Repository from the dropdown menu:

Bitbucket displays the Create a new repository page. Take time to review the dialog’s contents. Everything you enter on this page can be changed later. Select the project name (select create new project from the dropdown), enter the repository name, leave the private repository box checked (it will only be visible to you and those you give access to), and keep the rest of the defaults as they are. Click Create repository. Bitbucket creates your repository and displays the newly created repo page.

Take some time to explore the repository you have just created. The collapsable navigation sidebar on the left gives you access to common actions for a repository.

When you click Commits option in the sidebar, you’ll find that you have one initial commit generated from when you created your first repository with default settings. As you create content for your repository, you’ll see the commits section grow very quickly. Your repository is private so the only person who can create or edit content right now is you, the repository owner.

Step 2. Create an app password

Create app password so that you can connect to Bitbucket from the command line. App passwords are access tokens with reduced user access. These passwords can be useful for scripting, CI/CD tools, and testing Bitbucket connected applications while they are in development.

To create an App password:

  1. Select your avatar (Your profile and settings) from the navigation bar at the top of the screen.
  2. Under Settings, select Personal settings.
  3. On the sidebar, select App passwords.
  4. Select Create app password.
  5. Give the App password a name, usually related to the application that will use the password.
  6. Select the permissions the App password needs. For detailed descriptions of each permission, see: App password permissions.
  7. Select the Create button. The page will display the New app password dialog.
  8. Copy the generated password and either record or paste it into the application you want to give access. The password is only displayed once and can’t be retrieved later.

Clone Your Git Repo and Add Files

Now that you have a place to add and share your files, you need a way to get to it from your local system. To set that up, you want to copy the Bitbucket repository to your system. Git refers to copying a repository as ‘cloning’ it. When you clone a repo, you create a connection between the Bitbucket server (which Git knows as origin) and your local system.

Bitbucket server ‘Origin’ → Local system

Step 1. Clone your repo to your local system:

From your command line, navigate to a directory where you want to put your cloned repo:

$ cd bitbucket_repos/

From Bitbucket, go to your repository, click the clone button located to the right of the repo title. Bitbucket displays a popup clone dialog. Copy the highlighted clone command:

git clone https://nferg@bitbucket.org/nferg/demo-repo.git

from your terminal window, paste the command you copied from Bitbucket and press return. Enter your Bitbucket app password when the terminal asks for it. List the contents of your directory and you should see the directory cloned from Bitbucket.

$ ls
demo-repo/

Congratulations! You’ve cloned your repository to your local system.

Step 2. Add a file to your local repository and put it on Bitbucket

With the repository copied to your local system, it’s time to get to work. Let’s create a file. Go to your terminal window, navigate to the top level of the local directory for this project. In my case, I named it demo-repo:

$ cd demo-repo

Enter the following line into your terminal window to create a new text file ‘greeting.txt’ with ‘hello world’ as content:

$ echo "hello world" >> greeting.txt

If the command line doesn’t return anything, you’ve created the file with text correctly.

Get the status of your local repo. The git status command tells you about how your project is progressing in comparison to your Bitbucket repository. At this point, Git is aware that you’ve created a new file and you’ll see something like this:

$ git status
On branch master
Your branch is up to date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
greeting.txt
nothing added to commit but untracked files present (use "git add" to track)

The file is untracked, meaning that Git sees a file not part of a previous commit. The status output also shows the next step: adding the file.

Tell Git to track your new greeting.txt file using the git add command. Just like when you created a file, the git add command doesn’t return anything when you enter it correctly:

$ git add greeting.txt

The git add command moves changes from the working directory to the Git staging area. The staging area is where you prepare a snapshot of a set of changes before committing them to the official history.

Check the status of the file:

$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: greeting.txt

Now you can see the new file has been added (staged) and you can commit it when you are ready. The git status command displays the state of the working directory and the staged snapshot.

Issue the git commit command with a descriptive commit message ; -m indicates that a commit message follows:

$ git commit -m 'added new file'
[master 3c60f77] added new file
1 file changed, 1 insertion(+)
create mode 100644 greeting.txt

The git commit takes the staged snapshot and commits it to the project history. Combined with git add, this process defines the basic workflow for all Git users.

Everything we’ve done so far is on your local system and is invisible to your Bitbucket repository until you push those changes.

Go to your terminal window and send your committed changes to Bitbucket using git push origin master. This command specifies that you are pushing to the main branch (the branch on Bitbucket) on origin (the Bitbucket server). You should see something similar to the following:

$ git push origin master 
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 334 bytes | 334.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://bitbucket.org/nferg/demo-repo.git
349194c..3c60f77 master -> master

Your commits are now on the remote repository (origin).

Local system → Bitbucket server ‘Origin’

You can now go to your Bitbucket repository and see that we have the greeting.txt added to the repo along with a new commit message:

Pull Changes From Your Git Repo on Bitbucket

Next on our to do list is creating a file in Bitbucket.

Step 1. Create a file in Bitbucket

From your repository, click Source to open the source directory.

From the Source page, click the More options button(…) in the top right corner and select Add file from the menu.

A page for creating the new file opens:

Enter index in the filename field, select HTML from the Syntax mode list. Add some HTML code in the text box.

Click Commit. The Commit message field appears with the message:

Click Commit under the message field.

You now have a new file in Bitbucket! You are taken to a page with details of the commit, where you can see the change you just made:

If you want to see a list of the commits you’ve made so far, click Commits in the side bar.

Step 2. Pull changes from the remote repository

Now we need to get that new file into your local repo. The process is pretty straight forward, basically just the reverse of the push you used to get the greeting.txt file into Bitbucket.

To pull the file into your local repo, do the following:

Open your terminal window and navigate to the top level of your local repository. Enter the git pull --all command to pull all the changes from Bitbucket.

$ git pull --all
Fetching origin
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 294 bytes | 49.00 KiB/s, done.
From https://bitbucket.org/nferg/demo-repo
3c60f77..8294e4d master -> origin/master
Updating 3c60f77..8294e4d
Fast-forward
index | 1 +
1 file changed, 1 insertion(+)
create mode 100644 index

The git pull command merges the file from your remote repo (Bitbucket) into your local repository with a single command. Navigate to your repo folder on your local system and you’ll see the file index.html you just added.

Great! Up to this point, you have performed the basic Git workflow (clone, add, commit, push and pull) between Bitbucket and your local system.

Use a Git Branch to Merge a File

Branches are most powerful when you are working on a team. You can work on your own part of the project from your own branch, pull updates from Bitbucket and then merge all your work into the main branch when it’s ready.

As discussed earlier, a brunch represents an independent line of development for your repository. Think of it as a brand new working directory, staging area, and project history. Before you create any new branches, you automatically start out with the main branch.

Step 1. Create a branch and make a change

Branches are just pointers to commits. When you create a branch, all Git needs to do is create a new pointer — it doesn’t create a whole new set of files and folders.

To create a branch, do the following:

Go to your terminal window and navigate to the top level of your local repo. Create a branch:

$ git branch new-feature

This command creates a branch but doesn’t switch you to that branch. The repository history remains unchanged. All you get is a new pointer to the current branch. To begin working on the new branch, you have to check out the branch you want to use.

Checkout the new branch you just created to start using it:

$ git checkout new-feature
Switched to branch 'new-feature'

The git checkout command works hand-in-hand with git branch. Because you are creating a branch to work on something new, every time you create a new branch (using git branch), you want to make sure to check it out (using git checkout) if you are going to use it.

We find demo-repo on our local system and open it. Note that there no extra files or folders in the directory as a result of the new branch.

Let’s open the index.html file using a text editor and make a change:

<h1>Git is awesome!</h1>
<p>Git was developed in 2005 by Linus Torvalds.</p>

Save and close the file, and now enter git status in the terminal window. You’ll see something like this:

$ git status
On branch new-feature
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: index
no changes added to commit (use "git add" and/or "git commit -a")

Note On branch new-feature. Previously, we were on the main branch (master) because we only had one branch (main branch). Before you stage or commit a change, always check the branch where you want to add the change is checked out.

Stage your file:

$ git add index

Enter the git commit command with a commit message:

$ git commit index -m 'made change in a branch'
[new-feature d7d904e] made change in a branch
1 file changed, 2 insertions(+), 1 deletion(-)

We are now ready to merge the change that you just made back into the main branch.

Step 2. Merge your branch

Let’s enter the git status command one more time to be sure we have all the changes committed and to confirm what branch you have checked out:

$ git status
On branch new-feature
nothing to commit, working tree clean

Switch to the main (master) branch:

$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.

Merge changes from the new-feature branch into the master branch:

$ git merge new-feature
Updating 8294e4d..d7d904e
Fast-forward
index | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

You’ve essentially moved the pointer for the master branch forward to the current HEAD.

HEAD is Git’s way of referring to the current snapshot. Internally, the git checkout command simply updates the HEAD to point to either the specified branch or commit. When it points to a branch, Git doesn’t complain, but when you check out a commit, it switches into a ‘detached HEAD’ state. In a detached HEAD state, the HEAD does not point to any branch, but a specific commit or the remote repository.

If you are not planning to use the new-feature branch anymore, you can delete the branch:

$ git branch -d new-feature
Deleted branch new-feature (was d7d904e).

When you delete new-feature branch, you can still access the branch from master using commit id. For instance, if you want to undo the changes added from new-feature , use the commit id you just received to go back to that branch.

Enter git status to see the results of the merge:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean

To recap, here’s what we’ve done so far:

  • created a branch and checked it out
  • made a change in the new branch
  • committed the change to the new branch
  • integrated that change back into the main branch
  • deleted the branch we are no longer using

The last thing we need to do is push all the work back up to Bitbucket, your remote repository.

Step 3. Push your change to Bitbucket

To make your change visible for everyone, we push the current state of your local repo to Bitbucket.

For the repository directory in your terminal window, enter git push origin master to push the changes. The result looks something like this:

$ git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 339 bytes | 339.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
To https://bitbucket.org/nferg/demo-repo.git
8294e4d..d7d904e master -> master

Now click on the Source in the Bitbucket repo. If you open the index file, you’ll notice the change that we made in our local repo is now integrated into the master branch. And if you click on Commits, you can now see the most recent commit d7d904e:

Note the green straight line on the left of the commits list — it has a straight path and shows no branches. That is because the new-feature branch never interacted with the Bitbucket repo, only the change we created and committed. If you click Branches, notice that the page has no record of the new-feature brach either:

We are done!

Let’s review the Git commands that we’ve used:

  • git clone username@host:/path/to/repository — create a working copy of a local repository
  • git add <filename> — add one or more files to staging
  • git status — list the files you’ve changed and those you still need to add or commit
  • git commit -m “Commit message” — Commit changes to head (but not yet to the remote repository)
  • git push origin master — send changes to the master branch of your remote repository
  • git pull — fetch and merge changes on the remote server to your working directory
  • git branch — list all the branches in your repo, and also tell you what branch you’re currently in
  • git branch <branchname> — create a branch
  • git branch -d <branchname> — delete the feature branch
  • git checkout <branchname> — switch from one branch to another
  • git merge <branchname> — merge a different branch into your active branch

--

--

Nihal Parmar

Software Engineer @Crest Data System|| 6⭐ @HackerRank || Tech-Enthusiast || GSSoC’21 || Full Stack Developer