untracked files: (use "git add ..." to include in what will be committed)

Anybody says you should learn Git—and y'all should—but let'due south be honest: Git is kind of hard.

Even almost 10 years into my software development career, I am still learning about the underlying Git fundamentals and how to use Git more than effectively.

Information technology wasn't as well long agone that I realized I had a key misunderstanding of a key control I'd used countless times.

Like many other areas in programming, I believe the best way to larn is to just offset doing.

Simply start being productive with the tool—the fundamentals and edge cases will go sorted out over time.

Then in this tutorial that's exactly what we'll do. We'll work through a series of examples to build a from-the-ground-upward understanding of how to use Git and ultimately collaborate with your teammates.

In doing so, we'll use uncomplicated commands and explicate the underlying concepts as they're useful—merely merely to the extent that they aid understanding.

There's definitely a lot more to Git than is presented here, but these are things you lot'll learn as y'all work with it over time.

I as well will not be using any tree diagrams (like the one beneath) because they just misfile me, and I've never had to think nearly Git in this manner to be productive every bit a software developer.

hero
https://world wide web.atlassian.com/git/tutorials/using-branches/git-checkout

Here's what we'll cover. Don't let this list intimidate y'all, we'll go stride by step.

  • Installing git and setting upwardly a GitHub account
  • How to create a new repository in GitHub
  • Cloning the repository
  • Git branches
  • How the bank check the status of a Git project
  • How to brand our first commit
  • How to push upward our get-go commit to GitHub
  • How to add another commit in Git
  • How to phase changes in Git
  • How to view the Git unequal
  • How to collaborate with others in Git
  • Feature branches in Git
  • Git workflows for collaboration
  • How to merge a co-operative in Git
  • Pull request workflow
  • How to bring our local up to date
  • How to retrieve remote data
  • How to fix merge conflicts in Git
  • Review: how to start a new characteristic workflow
  • Conclusion

So with all of that said, I encourage you to follow along with the examples on your own car—permit'southward start!

How to install Git and fix a GitHub business relationship

Showtime, some irksome stuff we demand to do to get upwards and running.

If y'all already accept Git installed, have made a GitHub account (or use whatsoever other provider like GitLab or Bitbucket), and you have setup an SSH key, you tin can skip this section.

If not, y'all'll first need to install Git.

Secondly, we'll be using GitHub in this tutorial, so signup for a GitHub account here.

Subsequently you take a GitHub business relationship, you'll demand to create an SSH key to button your code from your local machine to GitHub (this key proves to GitHub when you lot push lawmaking that you are "you").

It'south not difficult—just follow the steps here.

How to create a new repository in GitHub

The adjacent matter nosotros'll practise is create a new repository in Github.

It's unproblematic. Just click the "New" repository button on your dwelling house page:

Screen-Shot-2021-03-31-at-7.30.33-PM
Creating a new repository

Adjacent, choose a name for the repository and whether y'all want the repo to be public or individual. You can optionally add a README file if you lot'd like, and so click "Create repository."

Screen-Shot-2021-03-31-at-7.29.07-PM
Configuring the new repo

I've called my repository applied-git-tutorial. This repo has all of the finished steps of this tutorial already in information technology, so if you lot want to you can always apply information technology as a reference.

How to clone a Git repository

To start, we'll "clone" the repo. Cloning a repo ways downloading all of the projection's code and metadata from the source—which in this case is GitHub.

To clone a repo, we employ git clone <URL>.

I used the URL from the repo I just created, merely you should use the URL of your own repository:

          $ git clone git@github.com:johnmosesman/practical-git-tutorial.git Cloning into 'applied-git-tutorial'... remote: Enumerating objects: 6, done. remote: Counting objects: 100% (6/6), done. remote: Compressing objects: 100% (iii/three), done. remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 0 Receiving objects: 100% (6/6), done.                  
Note: commands to be run in your terminal will be prefixed with a $.

We'll become into more detail nearly what git clone does soon, only for now just know that it downloads the project and places it in a folder in your current working directory.

Side by side let'due south change into the new directory using cd:

          $ cd practical-git-tutorial/ /applied-git-tutorial (main)$                  

We've inverse into the binder (which is just like any other folder), and your concluding may show yous something aslope the directory proper name: (main).

Git branches

This (main) ways that we are currently on a branch called main. Y'all tin think of a Git branch equally a copy of the project at a specific signal in time that can exist changed independently of other branches.

For case, if we used Git to track writing a book, we might have branches that look like this:

  • master branch
  • table-of-contents branch
  • chapter-1 branch
  • chapter-ii branch
  • etc.

The main branch is, well, the "main" branch—the identify where we're going to combine all of the contents of the book into one finalized, finished book.

Nosotros tin can create other branches to carve up and runway specific pieces of work.

If I was working on Chapter 1 and you were working on Chapter 2, we could create two difference branches, chapter-ane and chapter-2—effectively two dissimilar copies of the electric current status of the book.

We could and so both work on our respective chapters without stepping on each others' toes or changing the contents out from under each other—we both accept our own working copy that are dissever from each other.

When either of us are finished with our chapter, nosotros can add together the contents of our affiliate co-operative back into the main branch. When we're both finished, the main branch will contain both Chapter 1 and Chapter ii.

All the same, in that location are times where you will overwrite or alter the same piece of content equally someone else and we'll have to figure out how to settle those differences—and nosotros'll see that soon.

Annotation: depending on the projection you may meet a branch named master instead of master. It doesn't take any functional departure, just blazon master vs primary depending on what'due south in your project.

How to check the status of a Git project

One thing we'll do frequently is check the status of our project. What changes accept been fabricated and what practise we want to do with them?

To view the condition of our project we use git status:

          (principal)$ git status On branch master Your branch is up to date with 'origin/chief'.  nothing to commit, working tree clean                  

There's a few things in the outcome of this command, and so let's intermission those downwardly.

The commencement thing git status tells u.s.a. is we're on the primary branch:

                      On branch main        

The second sentence is a piddling more than interesting:

          Your branch is up to date with 'origin/main'.                  

Git is telling us that our branch is "up to date" with something called origin/main.

origin is a new concept known as a remote. A remote is a "remote source" different from your local machine.

In this projection we have our local copy of the projection, but we tin also add remote sources that we can collaborate with. After all, that is one of the biggest benefits of Git: controlled collaboration with others.

Continuing with our volume-writing example, if I write Chapter 1 on my auto and you write Affiliate 2 on your car, nosotros could both add each other's computers as "remotes" and ship and receive changes from each other.

In practice, the programming customs at large has decided that information technology is all-time to have a single source of truth for lawmaking. One place that is always "correct" well-nigh what the current state of the codebase is. By convention, we phone call this identify the origin.

In this instance, GitHub is our "origin."

In fact, we can see this by running the command git remote -v (-v for "verbose"):

          (main)$ git remote -v origin  git@github.com:johnmosesman/applied-git-tutorial.git (fetch) origin  git@github.com:johnmosesman/applied-git-tutorial.git (push)                  

This command lists all of our remotes. From the outcome we can run across that we accept a remote named origin, and the Git URL of this remote points to our repo on Github.com. This remote was automatically setup for us when nosotros ran git clone.

And so coming back to this argument in the consequence of git status:

Your branch is upwards to date with 'origin/primary'.

When we asked for the condition of our project, Git told us that our local main branch is up to date with the principal branch at our origin—which is GitHub.

In fact, git clone automatically created a main branch for usa locally because it saw that the origin we cloned from had a branch called master as its primary branch.

Basically, there are no changes on our local motorcar unlike from GitHub or vice versa—our local main co-operative and the GitHub master branch are identical.

As we make changes nosotros'll see this message change to reflect the differences in our local repository and the origin (GitHub) repository.

The final message from git status is about the land of the local project:

          nothing to commit, working tree make clean        

Nosotros'll go into more detail hither equally nosotros make changes, but this message is basically saying we haven't done anything—so no changes to report.

To summarize the consequence of git status:

  • We're on branch main
  • Our local main branch is identical to the origin's (GitHub's) main branch
  • We haven't fabricated whatsoever changes to the project yet

How to make our beginning commit

At present that we understand the initial land of our project, permit's make some changes and expect at the result.

Continuing with our book analogy, permit'south make a new file called chapter-1.txt and insert a judgement into it.

(You tin use the terminal commands beneath, or create and edit the file in any text editor you choose—it doesn't matter.)

          (main)$ impact chapter-1.txt (chief)$ echo "Chapter one - The Start" >> affiliate-one.txt (master)$ cat chapter-i.txt Affiliate i - The Kickoff                  

The commands above make a new file called affiliate-1.txt using impact, insert the sentence "Chapter i - The Commencement" using echo and the >> operator, and, to double-check our work, show the contents of the file using cat.

The result is a simple text file with one sentence in it.

Permit's run git status again and see the difference in its output:

          (master)$ git status On co-operative main Your branch is up to date with 'origin/main'.  Untracked files:   (utilise "git add together <file>..." to include in what will exist committed)         chapter-1.txt  zip added to commit just untracked files nowadays (use "git add" to track)                  

Here we run into a dissimilar output than earlier. We see a section describing "Untracked files," and our new file chapter-1.txt is listed there.

Before Git volition start tracking changes to a file we start take to tell Git to track it—and equally the bottom of the message states—we can apply git add to practise that:

          (main)$ git add together chapter-one.txt                  

(Instead of specifying the name of the file for git add, y'all can use a flow (.) to add all of the changes in the directory.)

Let's check the status again:

          (principal)$ git status On co-operative master Your branch is upwards to date with 'origin/chief'.  Changes to be committed:   (use "git restore --staged <file>..." to unstage)         new file:   chapter-1.txt  john:~/code/practical-git-tutorial (main)$                  

The bulletin has changed again. Information technology nows says that we have some changes that are ready to be "committed."

A commit in Git is a saved chunk of work, but it's a little unlike from the same save you lot would utilize to relieve a text file in a text editor.

You lot can recollect of a commit every bit a completed idea or unit of work.

For example, if we were continuing to write the contents of Chapter 1 in the book, information technology might look like this:

  • Write the title of the chapter. *click save in our editor*
  • Write the get-go paragraph of the chapter. *click save in our editor*
  • Write the second paragraph of the chapter. *click save once again*
  • Write the last paragraph of the chapter. *click save again*

Here, we've "saved" the document four times, but at the end of those 4 saves we now have the outset draft of our chapter, and that draft is one "unit of measurement of work."

Nosotros want to save this file on our calculator, but we besides want to signify that this is a unit of measurement of completed piece of work—even if information technology'southward merely a draft. It'south a chunk of piece of work worth holding onto. We may want to render to it in the hereafter, become dorsum and edit it, or merge this draft into the electric current typhoon of the entire book.

To do this, we create a new commit to signify this milestone. Each commit gets its ain unique identifier, and the order of the commits are preserved.

To commit our changes, they must get-go be added to the staging area by using git add.

(We'll talk more than nigh the staging area before long.)

Next, we need to finalize the commit by using git commit.

It's best practice to provide a detailed message of what changes you made—and more importantly—why you are committing these changes.

In one case the commit history becomes hundreds or thousands of commits long, it becomes nigh impossible to understand why a alter was made without a good commit message. Git will show us what files changed and what the changes were, simply the pregnant of those changes is up to us to provide.

Allow's commit the new file nosotros made with a commit message by using the -k or "bulletin" flag:

          (main)$ git commit -m "New chapter ane file with chapter heading" [main a8f8b95] New chapter ane file with chapter heading  1 file changed, ane insertion(+)  create style 100644 affiliate-one.txt                  

We've now committed that chunk of work, and we can see that by viewing the Git log via git log:

          (master)$ git log commit a8f8b95f19105fe10ed144fead9cab84520181e3 (HEAD -> main) Author: John Mosesman <johnmosesman@gmail.com> Date:   Fri Mar 19 12:27:35 2021 -0500      New affiliate 1 file with chapter heading  commit 2592324fae9c615a96f856a0d8b8fe1d2d8439f8 (origin/main, origin/Caput) Author: John Mosesman <johnmosesman@users.noreply.github.com> Date:   Wednesday Mar 17 08:48:25 2021 -0500      Update README.dr.  commit 024ea223ee4055ae82ee31fc605bbd8a5a3673a0 Author: John Mosesman <johnmosesman@users.noreply.github.com> Engagement:   Wed Mar 17 08:48:10 2021 -0500      Initial commit                  

Looking at this log, we see that at that place are 3 commits in the project history.

The latest commit is the one nosotros just made. We can see the aforementioned commit message we but used: "New affiliate 1 file...".

There are too ii previous commits: 1 when I initialized the projection and some other when I updated the README.md file on GitHub.

Detect that each commit has a long string of numbers and characters associated with it:

          commit a8f8b95f19105fe10ed144fead9cab84520181e3 (HEAD -> master)                  

This string of characters and numbers is chosen the SHA—it's the unique ID generated past a hashing algorithm for this commit. Just take note of these for now—we'll come back to this before long.

We also see two other interesting things in the log after the commit SHAs:

  • (HEAD -> principal) side by side to our latest commit
  • And (origin/master, origin/Caput) next to the commit before that 1.

This data tells united states the current status of our branches and remotes (equally far as nosotros know—but more on this later).

For the latest commit, nosotros meet that the Head (aka "where nosotros are at present" in the projection history) is pointing at our local main branch—represented by HEAD -> master.

This makes sense because we just made that commit, and nosotros haven't done anything else—nosotros're nevertheless at the indicate in fourth dimension where we made that commit.

If we look at the previous commit starting with 25923, we come across (origin/main, origin/HEAD). This tells us that, on the origin (aka GitHub), GitHub's Caput or "current identify" is on our previous commit.

Basically, our local machine thinks the latest change for local master branch is the commit where we added Chapter ane, and our local machine likewise thinks that on GitHub the latest change is the commit where I updated the README before I wrote this mail.

And this makes sense—nosotros oasis't told GitHub about the newest commit we made. GitHub however thinks that the repo is upwardly to date with what it has seen.

Now let'due south push button upwardly our new commit to GitHub.

How to push button upwards our first commit to GitHub

Nosotros have a new commit on our local machine and we demand to update our "source of truth"—the origin remote—aka GitHub.

We're currently on the main co-operative locally, so nosotros need to tell GitHub to update its own master with the new commit that nosotros fabricated.

To do that we use the git push control and we can specify where we want to button and what branch we want to push button to.

          (main)$ git push origin main Enumerating objects: four, done. Counting objects: 100% (4/four), done. Delta compression using upward to 16 threads Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 326 bytes | 326.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To github.com:johnmosesman/practical-git-tutorial.git    2592324..a8f8b95  principal -> main                  

Here nosotros pushed to the origin remote (GitHub) and to the main branch.

The output tells us about some file operations Git did to do that, and the terminal line of the output tells us which commits it pushed and to where:

          To github.com:johnmosesman/practical-git-tutorial.git    2592324..a8f8b95  main -> main                  

Here it shows united states of america that we pushed our main co-operative to GitHub's master branch.

If nosotros look dorsum at the git log output we'll notice that both our local and origin betoken to the aforementioned commit now:

          (main)$ git log commit f5b6e2f18f742e2b851e38f52a969dd921f72d2f (Caput -> primary, origin/main, origin/HEAD) Author: John Mosesman <johnmosesman@gmail.com> Appointment:   Monday Mar 22 10:07:35 2021 -0500      Added the intro line to chapter 1                  

In short, on origin (GitHub) the main branch (also written every bit origin/main) has now placed our new commit as the latest commit in the history.

If nosotros were working with other collaborators, they could now pull down our newest change from GitHub and begin editing the Chapter 1 as well.

How to add some other commit in Git

Before we offset collaborating with others, allow's make another small modify to meet what happens when nosotros edit an existing file.

Let's add another line into our Chapter ane file:

          (main)$ echo "Information technology was the best of times, it was the worst of times" >> chapter-1.txt (main)$ cat chapter-1.txt Chapter one - The Beginning It was the best of times, information technology was the worst of times                  

Using true cat we can run into that our file at present contains two lines.

Let's look at the status of our Git repo once more:

          (chief)$ git status On co-operative main Your co-operative is upward to date with 'origin/main'.  Changes not staged for commit:   (apply "git add <file>..." to update what will be committed)   (use "git restore <file>..." to discard changes in working directory)         modified:   chapter-1.txt  no changes added to commit (utilize "git add together" and/or "git commit -a")                  

Starting from the pinnacle, we'll notice the output says Your branch is up to date with 'origin/principal'.

This might seem odd to you since we just changed a file, but Git is only comparison the commits nosotros've made confronting the commits in origin/main.

The next section of the output explains information technology a trivial more than:

          Changes not staged for commit:   (use "git add <file>..." to update what will be committed)   (utilise "git restore <file>..." to discard changes in working directory)         modified:   chapter-1.txt                  

Here Git tells united states of america that we take "changes non staged for commit."

Before we can commit a set of changes, nosotros get-go have to stage them.

How to stage changes in Git

To illustrate the usefulness of the staging surface area, let's first stage our changes by using git add:

          (main)$ git add . (main)$ git status On branch principal Your co-operative is upward to date with 'origin/principal'.  Changes to exist committed:   (use "git restore --staged <file>..." to unstage)         modified:   affiliate-1.txt                  

These changes are now ready to be committed, only before we commit them let'due south add some other change into our chapter-1.txt file.

I'm going to supplant the contents of affiliate-1.txt entirely with new text:

Annotation: I'one thousand using > hither instead of >> which volition replace the contents of the file instead of appending to the file.
          (main)$ repeat "New file contents" > chapter-i.txt  (main)$ cat chapter-1.txt New file contents  (primary)$ git status On branch main Your co-operative is up to date with 'origin/primary'.  Changes to exist committed:   (use "git restore --staged <file>..." to unstage)         modified:   chapter-i.txt  Changes not staged for commit:   (use "git add <file>..." to update what will be committed)   (utilize "git restore <file>..." to discard changes in working directory)         modified:   chapter-1.txt                  

From the output we can encounter that we at present have staged changes, and not staged changes.

While the file itself can just comprise one matter, Git keeps rails of both changes for usa—even though they're changes to the same lines!

Even so, from the output above we can't really tell what those changes were—we merely know that they be.

To view these changes, we'll outset wait at the command line manner (which I never use), and so a style that uses a GUI (which is 100% nicer).

How to view the Git diff

To view the changes, we demand to look at the Git diff.

A diff (brusk for difference) is the deviation between two sets of changes. Those changes could be anything from staged changes to not-staged changes to commits.

The control line manner to do this is by using git diff.

We'll look at this output in our simple case here simply for completeness' sake. But, as I mentioned before, nosotros're interested in effective Git workflows, and once y'all get to changes of any decent size across multiple files this command line output simply becomes not constructive.

But for completeness, here it is:

          (main)$ git unequal diff --git a/chapter-1.txt b/chapter-i.txt index 0450d87..4cbeaee 100644 --- a/chapter-1.txt +++ b/chapter-1.txt @@ -i,2 +one @@ -Chapter 1 - The Beginning -It was the best of times, it was the worst of times +New file contents                  

My terminal attempts to colorize this output to help with readability, but the of import parts to detect here is it tells united states what file nosotros're diffing, affiliate-one.txt, and at the bottom it shows us the actual differences. Let'south fundamental in on those lines:

          -Chapter 1 - The Kickoff -It was the best of times, information technology was the worst of times +New file contents                  

The lines starting with a minus sign (-) are lines we deleted entirely or in part, and the lines starting with a + sign represent lines added entirely or in part.

At present, with multiple files and many lines changed this output becomes unwieldy—fast. There is a better way, and even almost ten years into my programming career I still use a simple GUI program to help look at and manage diffs.

The program I employ is called GitX, and information technology'south an quondam and outdated piece of software that'southward not even really being maintained anymore. Still, I but apply it to view and manage file diffs—so it works for me.

I wouldn't particularly recommend this one, merely it is free. Although I've never used it, the GitHub Desktop client is probably a expert pick.

Now with that little aside out of the way, here'south what the unequal looks similar in my tool.

To start, the staged changes on the right-mitt side bear witness our original add together of the second judgement:

staged_changes
Staged changes in GitX

In the unstaged changes on the left-hand side, we run across the removal of those ii lines entirely and the addition of a new line:

unstaged_changes
Unstaged changes in GitX

This corresponds to the file replace command we ran.

It is and so much easier to understand the diff in a GUI program. This program also allows me to quickly switch between staging and un-staging files by just dragging them around. I tin can even stage or united nations-stage individual lines in a file dorsum and along as well.

At that place's no bonus points for using the command line vs a GUI program. Use whatever gets the task done for you.

Now that we've seen how the staging surface area and Git diffs piece of work, let's discard our non-staged changes and then nosotros can get back to committing our first change.

In my GUI plan I can right-click the file and click "Discard changes", simply I'll show the command line version hither as well.

The output of our final git status actually showed us how to do this by using git restore. Nosotros can pass the file path or merely a . for the whole directory:

          (principal)$ git restore .                  

If we check the status again nosotros're back to just our staged changes, and we tin continue.

Note: Git only commits changes that are staged, so we could have left those unstaged changes in our working directory and it wouldn't interfere with the committing process.

All the same, it would make our future changes more than cumbersome to deal with—so it makes sense to discard those changes to keep our working directory in good shape.

Now allow'southward finally commit these changes with a message nigh what we did:

          (main)$ git commit -m "Added the intro line to chapter 1" [primary f5b6e2f] Added the intro line to chapter i  1 file changed, 1 insertion(+)                  

Checking the condition once once again shows us that our branch is "ahead of 'origin/main' by i commit":

          (main)$ git condition On branch principal Your branch is alee of 'origin/primary' by 1 commit.   (use "git button" to publish your local commits)  nothing to commit, working tree clean                  

Finally allow's push upwardly our change:

          (main)$ git button origin primary                  

How to collaborate with others in Git

So far we've been looking at the simplest use case: working by ourselves on i co-operative.

In reality, we'll usually be working with multiple people working on multiple unlike branches. This is the real power of Git subsequently all: a organisation to interact and rail changes over fourth dimension amongst many collaborators.

For now, let's continue working as if nosotros're the only person on the projection, but let's adjust our workflow a niggling bit to set for when that's not the instance.

In general, information technology'due south best do to not piece of work direct on the chief branch.

The principal branch is supposed to be the "source of truth" for the project—changes to it should exist advisedly reviewed. Any change in origin/principal becomes the new "source of truth" for anyone else working on the project, and so nosotros shouldn't merely change information technology without some thought and review by others.

Instead of working on main straight, let'due south co-operative off of primary into our own feature branch, and then merge those changes back into main.

That'south a lot of new terminology, and then permit'south take it one step at a time.

Characteristic branches in Git

To begin, permit's branch off of main and create our own characteristic branch to work on.

When yous create a co-operative off of some other branch, you create a re-create of that branch at that indicate in time. You can now change this new branch independently of the original branch.

To try this out, let's brand a new branch called chapter-ii. To do this we employ git checkout with the -b flag and the proper noun we want the new branch to take:

          (main)$ git checkout -b chapter-2 Switched to a new branch 'chapter-2' (affiliate-2)$                  

Discover that the terminal now shows us on the affiliate-2 branch. Changes on the chapter-2 branch will non touch on the main branch at all. Nosotros essentially have a new playground to make whatsoever changes nosotros want to make without affecting chief.

At that place are interesting things happening under the hood here, simply for the purpose of this tutorial we just need to know that to "checkout" something in Git means to "change my local projection to look exactly like the projection looked at some specific signal in fourth dimension." You can think of a branch every bit a pointer to a specific timeline of the Git history.

There's a lot more happening here, but that definition should exist expert enough for now.

So nosotros have a new co-operative, and for now that new branch is identical to main (we oasis't made any changes notwithstanding).

Next permit's repeat what we've already done before and create a new file chosen chapter-2.txt, requite it some content, and commit it:

          (affiliate-2)$ impact affiliate-2.txt (chapter-ii)$ repeat "Chapter two - The next affiliate" >> chapter-two.txt  (chapter-2)$ git status On branch affiliate-2 Untracked files:   (use "git add <file>..." to include in what will be committed)         affiliate-2.txt  zilch added to commit but untracked files present (use "git add" to rails)  (chapter-2)$ git add .  (chapter-ii)$ git commit -m "Creates chapter ii and adds the topic sentence" [chapter-2 741822a] Creates chapter 2 and adds the topic sentence  i file changed, 1 insertion(+)  create fashion 100644 affiliate-2.txt                  

Nothing new in there—only the same affair we did for Chapter 1.

At present that nosotros take a new commit on our chapter-2 branch, permit's look the Git log and compare this new branch to main:

          (chapter-two)$ git log commit 741822a9fd7b15b6e3caf437dd0617fabf918449 (Head -> affiliate-2) Author: John Mosesman <johnmosesman@gmail.com> Appointment:   Monday Mar 22 10:33:26 2021 -0500      Creates affiliate two and adds the topic sentence  commit f5b6e2f18f742e2b851e38f52a969dd921f72d2f (origin/principal, origin/HEAD, principal) Author: John Mosesman <johnmosesman@gmail.com> Date:   Mon Mar 22 10:07:35 2021 -0500      Added the intro line to chapter 1  commit a8f8b95f19105fe10ed144fead9cab84520181e3 Author: John Mosesman <johnmosesman@gmail.com> Date:   Friday Mar 19 12:27:35 2021 -0500      New chapter one file with affiliate heading ...                  

We'll notice in the log that our latest commit is shown at the top, and our HEAD is again different from our origin. This again makes sense—we've made changes locally that aren't in GitHub.

Now we need to go our new changes into the main branch.

Git workflows for collaboration

There are a couple of ways to get our new Affiliate two into the main branch and into GitHub, and the style we choose depends on the projection and what workflow we're using to interact with others.

First allow's talk about a couple different workflows we could use.

The showtime one is the most straightforward:

  1. Merge changes from chapter-two into our local main co-operative
  2. Push local chief branch to origin/primary

The second way is a footling more complicated:

  • Button our local chapter-2 co-operative to origin (this creates a new branch on origin chosen origin/chapter-2)
  • Merge origin/chapter-2 into origin/main on GitHub
  • Pull down the new changes from origin/main into our local main

The first workflow is definitely easier, and it is something I would use if I was working on this projection by myself without any other collaborators.

Nonetheless, if I had collaborators, I wouldn't desire to push straight to the main co-operative from my local. By doing so I would be irresolute and taking control of the history of the projection solely on my own changes—without any input or review from collaborators.

For this reason, if in that location were multiple people working on the same project, I would employ the 2nd workflow because it is a ameliorate collaboration process for the team.

That beingness said, we'll get over both workflows, and allow's start with the showtime ane which is less complicated.

How to merge a co-operative in Git

When y'all desire to combine the contents of two branches into ane in Git, there are a few methods of doing and then. The beginning and probably simplest way is to do a merge.

A merge, like it sounds, tries to take the contents of ane branch and apply (or "merge in") those changes into some other branch.

In our scenario, nosotros desire to accept the contents of the affiliate-2 branch and merge them into main. Said another manner, we want to take the current land of principal and add in our changes from the chapter-2 branch.

We tin can do this by using git merge, and we'll look at the outcome of it later on.

The outset thing we need to do is exist on the primary co-operative that we want to merge changes into. Since we desire main to absorb the changes from affiliate-2, nosotros showtime need to be on the main branch.

To switch dorsum to the principal branch, we can again utilize git checkout and specify the branch name of principal. This time we don't utilize the -b flag considering nosotros want to switch to an existing co-operative and non create a new 1:

          (affiliate-2)$ git checkout main Switched to branch 'primary' Your branch is up to engagement with 'origin/main'. (main)$                  

Nosotros're now back on the chief branch, and we get a quick status message saying nosotros're up to appointment with origin/main.

Next, let'south merge our chapter-2 branch into master:

          (main)$ git merge chapter-2 Updating f5b6e2f..741822a Fast-forward  chapter-2.txt | i +  1 file inverse, 1 insertion(+)  create style 100644 chapter-2.txt                  

Let's await at the Git log once more to come across the effect:

          (main)$ git log commit 741822a9fd7b15b6e3caf437dd0617fabf918449 (Caput -> master, chapter-2) Author: John Mosesman <johnmosesman@gmail.com> Appointment:   Mon Mar 22 10:33:26 2021 -0500      Creates affiliate 2 and adds the topic sentence  commit f5b6e2f18f742e2b851e38f52a969dd921f72d2f (origin/principal, origin/Caput) Author: John Mosesman <johnmosesman@gmail.com> Date:   Mon Mar 22 10:07:35 2021 -0500      Added the intro line to chapter i      ...                  

We can see that our main branch at present contains the new commit from affiliate-ii, and that our origin is still at the previous commit (as we oasis't updated origin yet).

Finally, let's push button our changes up to origin/main:

          (primary)$ git push button origin chief Full 0 (delta 0), reused 0 (delta 0) To github.com:johnmosesman/applied-git-tutorial.git    f5b6e2f..741822a  master -> master                  

Nosotros've successfully merge our chapter-2 co-operative, and pushed that change upwards to GitHub!

Every bit a last cleanup stride, let'south delete the affiliate-2 characteristic branch as information technology has already been merged into main:

          (main)$ git branch -d chapter-2 Deleted co-operative affiliate-2 (was 741822a).                  
Note: the git branch command without a co-operative proper noun argument will list all of the branches yous accept locally.

Adding the -d flag and a branch proper name deletes the branch passed in.

Pull asking workflow

To work through our collaboration workflow, let's echo the same matter we've done with Chapter 1 & 2 on a new branch called chapter-3:

(Now would be a practiced time to try this on your own!)

          (main)$ git checkout -b affiliate-3 (affiliate-3)$ touch affiliate-3.txt (chapter-3)$ echo "Chapter 3 - The End?" >> affiliate-3.txt (affiliate-3)$ git add . (chapter-3)$ git commit -m "Adds Chapter 3"                  

At present we have a new commit on a new branch called affiliate-3.

Let'south review how we're going to get this new co-operative merged into master without acting directly on main ourselves:

  • Push our local chapter-three branch to origin (this creates a new branch on origin chosen origin/chapter-three)
  • Merge origin/chapter-3 into origin/principal on GitHub
  • Pull down the new changes from origin/master into our local main

A couple more steps—but none that are too complicated.

The first pace is to push button our new co-operative to GitHub. Since this branch doesn't exist nevertheless on GitHub, GitHub will make a new co-operative for us that is a copy of what we pushed:

          (chapter-iii)$ git push origin chapter-3 Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Delta compression using up to xvi threads Compressing objects: 100% (2/2), washed. Writing objects: 100% (three/three), 299 bytes | 299.00 KiB/s, done. Total 3 (delta 1), reused 0 (delta 0) remote: Resolving deltas: 100% (one/1), completed with 1 local object. remote: remote: Create a pull asking for 'chapter-three' on GitHub by visiting: remote:      https://github.com/johnmosesman/applied-git-tutorial/pull/new/affiliate-3 remote: To github.com:johnmosesman/practical-git-tutorial.git  * [new branch]      affiliate-3 -> chapter-3                  

Now that we have our co-operative on GitHub, we tin can create a pull request to be reviewed past our teammates.

GitHub even provides us with the URL to visit in our output higher up: https://github.com/johnmosesman/applied-git-tutorial/pull/new/chapter-iii

A couple notes: this next part shows GitHub's UI and process for pull requests, just this process should exist very similar for other services (like GitLab, Bitbucket, etc.).

Also go along in mind I'm using my own repo, then some of the URLs you encounter here will be different from yours.

Visiting the URL above, nosotros go far at a page to open a new pull request.

We come across a few things:

  • A place to specify the proper noun of the pull request (a topic sentence to easily sympathize what this PR is about)
  • A box for a description to explicate the changes nosotros made and whatever other context we want to provide (you can as well add images, gifs, or videos here equally well)
  • And beneath all of that is the list of files we changed and the changes in them (the diff).
Screen-Shot-2021-03-24-at-10.22.13-AM
Opening a new pull request

Discover that the UI shows base: main <- compare: affiliate-3. This is GitHub telling us that we're setting the pull request to merge chapter-three into principal.

Below the pull request description is the diff of the changes nosotros fabricated:

Screen-Shot-2021-03-24-at-10.26.42-AM
The pull request diff

We'll find that merely the file chapter-three.txt is shown, and this is because information technology'due south the merely file that nosotros changed.

There are other files currently in our project (affiliate-1.txt, chapter-two.txt), but those files didn't change and so in that location'due south no need to testify them.

Nosotros meet the one line nosotros inserted into affiliate-3.txt—signified by a + sign at the start of the line and the greenish background which signifies an addition to the file.

Later clicking "Create Pull Request" we're taken to the new PR we just fabricated.

At this signal we could assign a reviewer to the PR and have a back-and-forth discussion effectually the lawmaking past leaving comments on specific lines in the unequal. After the code has been reviewed and we make any changes that demand to be made, nosotros're ready to merge.

For this sake of this tutorial we'll skip the review process, and merely click the big green merge button:

Screen-Shot-2021-03-24-at-10.39.55-AM
Merged pull request

And with that, our pull asking has been merged into main!

How to bring our local up to date

We've at present made a change to origin/main in a safe, controlled, and peer-reviewed style.

But, our local doesn't know annihilation virtually this change. Locally, Git nonetheless thinks we're on our chapter-3 co-operative which isn't merged into main:

          (chapter-three)$ git log commit 085ca1ce2d0010fdaa1c0ffc23ff880091ce1692 (HEAD -> chapter-iii, origin/affiliate-iii) Writer: John Mosesman <johnmosesman@gmail.com> Date:   Tue Mar 23 09:19:14 2021 -0500      Adds Chapter three  commit 741822a9fd7b15b6e3caf437dd0617fabf918449 (origin/chief, origin/Head, main) Author: John Mosesman <johnmosesman@gmail.com> Date:   Mon Mar 22 10:33:26 2021 -0500      Creates chapter 2 and adds the topic judgement  ...                  

Our local shows origin/chief on the previous commit starting with 741822. Nosotros need to pull in the new information from our origin to update our local repository.

How to retrieve remote data

As with many other things with Git, at that place are many dissimilar methods to reach the same chore.

For our purposes, nosotros'll await at a straightforward style that will work in the majority of cases.

To kickoff, let'due south switch back to our main co-operative locally:

          (affiliate-3)$ git checkout main Switched to branch 'main' Your co-operative is up to date with 'origin/primary'.                  

Our local thinks we're up to appointment with origin/chief considering we oasis't asked the remote repository (origin) for new data since we pulled the project at the beginning using git clone.

Git repositories are not live-updating—they're just a snapshot of the history at a indicate in fourth dimension. To receive any new data near the repository nosotros have to ask for it once again.

To recollect any new information that has changed on the remote, we utilize git fetch:

          (main)$ git fetch From github.com:johnmosesman/practical-git-tutorial    741822a..10630f2  main       -> origin/main                  

The output shows us that origin/chief is now pointing to a commit starting with 10630f2. This commit prefix matches the SHA of the merge commit of our pull asking.

At that place are a few ways to merge 2 branches into i another, and one of those means is by creating a merge commit. That's what happened here.

commit
The merge commit of our PR

Our local repository now knows about the presence of these new commits, simply nosotros oasis't done anything with them yet.

Running git fetch doesn't actually change any of our files—it just downloads new information from the remote nigh the condition of the repo.

Now that our local repository is enlightened of the status of each branch (but hasn't changed or updated any of the branches), let's check our condition again:

          (main)$ git status Your branch is behind 'origin/main' by 2 commits, and can exist fast-forwarded.   (employ "git pull" to update your local co-operative)                  

Our local now knows that our local primary is backside origin/master past 2 commits (the commit from the chapter-iii branch and the PR merge commit).

It besides gives us the hint to use git pull to update our local branch:

          john:~/code/practical-git-tutorial (main)$ git pull origin chief From github.com:johnmosesman/practical-git-tutorial  * branch            master       -> FETCH_HEAD Updating 741822a..10630f2 Fast-forward  chapter-three.txt | 1 +  1 file changed, i insertion(+)  create style 100644 chapter-3.txt                  

The git pull command is actually a shorthand for running two commands: git fetch followed by a git merge.

Since git fetch doesn't apply any changes locally, it tin can be useful to use git fetch to come across if our branches are up to appointment with the remote (possibly we don't want to merge in the changes withal), or to pull down new branches that exist on the remote and not on our local motorcar.

Fetching a new branch from a remote will go alee and download that branch also to your local machine—since information technology'south a new co-operative information technology won't conflict with anything in your local setup.

Nosotros could accept just done a git pull initially instead of starting time doing a git fetch, but I wanted to explain git fetch equally information technology is useful in its ain correct.

After running git pull, if we run git status one time again we'll see that everything is up to date.

And with that, we've pulled in changes from our remote and got our local up to date!

How to fix merge conflicts in Git

The final topic we'll cover is how to bargain with conflicts.

So far, Git has just magically handled all of the file updating, and most of the fourth dimension Git tin merely handle it. But, there are times when Git doesn't know how to combine changes together, and that creates a disharmonize.

A conflict occurs when merging two changes that have changed the same line in a file. If two commits accept changed the same line in a file, Git doesn't know which commit's changes to use, and information technology volition require you to brand the choice.

To setup this scenario, I've created some other branch on Github called chapter-3-collaboration. Let'south imagine that a teammate has already started working on this branch and they've asked you to collaborate with them in finishing out Chapter 3.

Since this is a new branch that we don't take locally, nosotros tin can apply git fetch to call back the new branch data from the remote, and then switch to that branch using git checkout:

          (main)$ git fetch From github.com:johnmosesman/practical-git-tutorial  * [new co-operative]      chapter-3-collaboration -> origin/chapter-3-collaboration  (primary)$ git checkout chapter-three-collaboration Branch 'chapter-3-collaboration' fix up to track remote branch 'chapter-3-collaboration' from 'origin'. Switched to a new branch 'affiliate-3-collaboration' (chapter-3-collaboration)$                  

We've now pulled downward the new branch to our local repository and switched to it. This is the contents of chapter-3.txt on this new branch currently:

          (affiliate-3-collaboration)$ cat chapter-3.txt Chapter 3 - The End?  This is a sentence.                  

It's a title and i sentence. Permit's change the title to something new similar "Chapter 3 - The End Is Only The Commencement."

The contents of chapter-3.txt now look like this:

          (chapter-3-collaboration)$ cat chapter-3.txt Chapter 3 - The Finish Is Just The Beginning  This is a sentence.                  

After committing that change, if we try to push button it upwards nosotros become this message:

          (chapter-3-collaboration)$ git push button origin chapter-3-collaboration To github.com:johnmosesman/practical-git-tutorial.git  ! [rejected]        chapter-3-collaboration -> chapter-3-collaboration (non-fast-forward) error: failed to button some refs to 'git@github.com:johnmosesman/practical-git-tutorial.git' hint: Updates were rejected because the tip of your current branch is behind hint: its remote counterpart. Integrate the remote changes (due east.g. hint: 'git pull ...') before pushing again. hint: See the 'Note virtually fast-forwards' in 'git button --help' for details.                  

Our teammate has already made some commits before nosotros did, and pushed it to the remote branch. Our local branch is now out of date with the remote, and GitHub is denying our button until we merge in the changes from our teammate:

          ... the tip of your electric current co-operative is behind its remote counterpart. Integrate the remote changes ... before pushing over again.                  

It also gives us a hint about how to do that: git pull.

          (chapter-3-collaboration)$ git pull origin chapter-iii-collaboration From github.com:johnmosesman/applied-git-tutorial  * branch            chapter-iii-collaboration -> FETCH_HEAD Auto-merging chapter-3.txt CONFLICT (content): Merge conflict in chapter-iii.txt Automatic merge failed; fix conflicts and then commit the result.                  

Later pulling—and every bit we might have expected given the topic we're currently discussing—we have a merge conflict.

Git tried to automatically merge our teammate'south changes into ours, but there was a identify in the file that it couldn't automatically merge—we both changed the same line.

Git stopped "mid-merge" and is telling u.s. nosotros need to prepare the merge conflicts before information technology can finish the merge. Let's wait at our git status currently:

          (chapter-three-collaboration)$ git status On branch chapter-three-collaboration Your branch and 'origin/chapter-3-collaboration' have diverged, and have 1 and 1 different commits each, respectively.   (utilize "git pull" to merge the remote co-operative into yours)  Yous have unmerged paths.   (prepare conflicts and run "git commit")   (apply "git merge --arrest" to abort the merge)  Unmerged paths:   (use "git add <file>..." to mark resolution)         both modified:   chapter-3.txt  no changes added to commit (employ "git add together" and/or "git commit -a")                  

Git tells united states of america our branch and the remote co-operative have 1 commit dissimilar from each other. Information technology as well tells us that we have some "unmerged paths"—that we're currently mid-merge and we demand to gear up the conflicts.

Information technology shows us chapter-3.txt is currently modified, then let's look at the contents of chapter-3.txt:

          (chapter-iii-collaboration)$ cat chapter-iii.txt <<<<<<< Caput Chapter 3 - The End Is Just The First ======= Chapter 3 - The Cease But Not The Ending >>>>>>> 2f6874f650a6a9d2b7ccefa7c9618deb1d45541e  This is a sentence.                  

Git has added some markers to the file to show us where the conflict happened. Both nosotros and our teammate changed the title judgement, so information technology's surrounded by Git's markers of a disharmonize: <<< and >>> arrows separated by a line of ===.

The pinnacle line, signified by <<<<<<< HEAD and followed by "Affiliate 3 - The End Is Only The Beginning", is the alter that we merely made. Git is telling usa that this line is where our current Head is at—i.e., this is the modify at our electric current commit.

The line below it, "Affiliate 3 - The End Merely Not The Ending" followed by >>>>>>> 2f6874f650a6a9d2b7ccefa7c9618deb1d45541e, is the line and commit from our teammate.

Basically, Git is telling us, "Which ane of these lines (or some combination of these lines) do y'all want to keep?"

Notice that the line at the lesser file isn't wrapped upward in the conflicts—it wasn't inverse by both commits.

We need to resolve the conflict by deleting one of the lines or combining the 2 lines into 1 (and remember to remove all of the extra markers that Git put in in that location as well).

I'm going to accept a combination of these lines, and so the terminal file looks similar this:

          (chapter-iii-collaboration)$ cat affiliate-iii.txt Chapter 3 - The End Is Not The Ending--Simply Only The Beginning  This is a sentence.                  

To finish the merge, we just need to commit our disharmonize resolution:

          (chapter-3-collaboration)$ git add together . (chapter-3-collaboration)$ git commit -m "Merge new title from teammate" [chapter-3-collaboration bd621aa] Merge new championship from teammate  (chapter-three-collaboration)$ git status On branch chapter-three-collaboration Your co-operative is ahead of 'origin/chapter-3-collaboration' by 2 commits.   (use "git push" to publish your local commits)  zippo to commit, working tree clean                  

The result of git condition tells us that our local branch is is ahead of 'origin/chapter-3-collaboration' by ii commits..

Looking at the git log confirms this:

          commit bd621aa0e491a291af409283f5fd1f68407b94e0 (Head -> chapter-iii-collaboration) Merge: 74ed9b0 2f6874f Author: John Mosesman <johnmosesman@gmail.com> Date:   Thu Mar 25 09:20:42 2021 -0500      Merge new title from teammate  commit 74ed9b0d0d9154c912e1f194f04dbd6abea602e6 Author: John Mosesman <johnmosesman@gmail.com> Date:   Thu Mar 25 09:02:03 2021 -0500      New title  commit 2f6874f650a6a9d2b7ccefa7c9618deb1d45541e (origin/chapter-three-collaboration) Writer: John Mosesman <johnmosesman@gmail.com> Date:   Thu Mar 25 08:58:58 2021 -0500      Update title  ...                  

The resulting commit history has both of the commits on the co-operative and our merge commit at the top.

From here, we only need to push up our changes to the remote:

          (affiliate-three-collaboration)$ git push origin chapter-3-collaboration Enumerating objects: 10, done. Counting objects: 100% (10/x), done. Delta compression using up to 16 threads Compressing objects: 100% (6/vi), done. Writing objects: 100% (6/6), 647 bytes | 647.00 KiB/s, done. Total 6 (delta 2), reused 0 (delta 0) remote: Resolving deltas: 100% (2/two), completed with one local object. To github.com:johnmosesman/practical-git-tutorial.git    2f6874f..bd621aa  affiliate-3-collaboration -> affiliate-3-collaboration                  

Now that we've changed the remote branch, our teammate would demand to do a git pull to merge in our new merged changes.

And, ideally we would tell our teammate that we pushed upwards a new change so they could pull it down before they continue editing—reducing the likelihood they'll have to fix a merge conflict in the future, too.

Branches off of branches

We could have also created our own branch off of the chapter-iii-collaboration branch. This would let us piece of work without having to worry nigh merge conflicts until the very terminate.

Once we had finished our work in our ain carve up branch, we could then merge our feature branch into our teammate's feature branch—and then into main.

chapter-3-collaboration-john -> chapter-3-collaboration -> main

As yous can run across the branch structure tin can get quite complicated every bit more and more branches branch off of each other and become ahead of and behind each other.

Because of this, information technology's generally a good idea to keep branches modest and isolated and endeavour to merge them apace and often.

This can help avoid a lot of painful merge conflicts.

Review: how to kickoff a new feature workflow

I'll stop with a quick review of how to arroyo starting a new task and the commands and flows to do it.

Say you've been given your first ticket at a new job: a small issues to squash in your team's product.

The beginning affair you'd need to do is pull downwards the repo using git clone <URL>.

Next, you'd want to make a feature branch off of principal using git checkout -b <BRANCH_NAME>. After that, you'd fix the bug and commit the change(s) using git add and git commit.

Maybe solving this problem takes multiple commits—or peradventure y'all brand a few commits in an attempt to solve it before you finally get in at the solution. That's ok too.

After committing, you push your new branch to the origin (git button origin <BRANCH_NAME>) and create a pull request. Subsequently a code review your branch is merged in (yay!).

You've now completed your characteristic, and it's time to switch back to principal (using git checkout principal), employ git pull to get your latest changes plus whatsoever other changes other people have made, and beginning off again with a new co-operative.

Determination

As mentioned in the beginning, there are many ways to arroyo working with Git and Git workflows.

In that location'south also a lot of underlying Git "magic" (that is, code being run that you don't understand yet), simply you will learn and choice upwards more of this with time.

I spent the first many years of my career just using memorized commands and workflows. It worked. As I ran into problems or collaborated with teammates I learned more and eventually my skill with Git expanded.

In the start, don't make it any harder than it has to be! You lot will acquire over time.

If yous liked this commodity, I write about technical topics like this also equally non-technical topics on my site.

I also write similar things on Twitter: @johnmosesman.

Either way, experience free to send me a message.

Thank you for reading!

John

Learn to lawmaking for gratuitous. freeCodeCamp's open source curriculum has helped more than xl,000 people get jobs as developers. Get started

willinghamjoods1973.blogspot.com

Source: https://www.freecodecamp.org/news/practical-git-and-git-workflows/

0 Response to "untracked files: (use "git add ..." to include in what will be committed)"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel