HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

A git/GitHub primer

hgtonighthgtonight MVP
edited November 2015 in Tutorials

How do I get started with git and GitHub?

You will need two things: git and a GitHub account. Both are free!

Go to https://github.com/join an sign up. Be sure to select the free plan.

If you are completely new to git, I highly suggest running the GitHub clients as a way to get your feet wet. You can get the Windows version here: https://windows.github.com/
You can get the Mac version here: https://mac.github.com/

If you are running Linux, you can get the latest version here: http://git-scm.com/download/linux
After you installed git, configure it per this guide: https://help.github.com/articles/set-up-git#set-up-git

Congratulations, you now have git running on your local computer!

Now what?

Assuming you are doing this to work on Vanilla Forums, the next thing you want to do is fork Vanilla Forums, Inc.'s repository on GitHub. You can find the core Vanilla repository here: https://github.com/vanilla/vanilla

If you are signed in to GitHub, you can fork the repository by clicking on the forking icon in the upper right hand corner of the page.

Wait, what is a fork?

A fork is a clone of a repository you don't have write access to. It contains everything in the original repo and its history.

You can do anything you want with this version. You own it. Doesn't open source rock?

Once you have successfully forked the Vanilla repository, you probably want to clone that repo to your local machine. You can do this by either clicking on the Clone in Desktop button on your forked repo at GitHub, or by opening your terminal and using the following commands:

mkdir ~/projects
cd ~/projects
git clone https://github.com/hgtonight/vanilla.git

This will create a folder in your home folder called projects and clone my forked vanilla repository into the folder called vanilla. Be sure to replace my username (hgtonight) with your GitHub username.

Once that is done, we have a full copy of the repo hosted on GitHub on our local computer. If we direct our localhost to serve the ~/projects/vanilla folder, we can make changes to the source and see what happens in our browser.

We need to switch to the proper branch if we want to work on the open source version. The current stable version of Vanilla is 2.1, so we need to checkout the 2.1 branch:

git checkout 2.1

We can start hacking at this point, but we want to keep our fork up to date. We can do this by adding the original repo (vanilla/vanilla) as a remote source to our forked repo and periodically pull in the changes. This is done the following way:

git remote add upstream git://github.com/vanilla/vanilla.git

Once this is done, we now have two remote repositories that can be used to update the local repo. You can retrieve a remote repo using the fetch command. Let's do that right now.

git fetch upstream

This will check the upstream for any changes since the last fetch and transfer them to your local machine. If there are some changes in Vanilla's 2.1 branch, we can pull them into our local repo with:

git checkout 2.1
git fetch upstream
git merge upstream/2.1

This will merge in the remote source upstream's 2.1 branch into our local 2.1 branch. That is a lot of typing and you can use the pull command to turn that into one command.

git pull upstream 2.1

It is a good idea to periodically pull in upstream's commits so you stay up to date. Knowing this, you should now have a fork of Vanilla that you can update using git.

OK, but what if I want to submit some changes?

As an exercise, we are going to make a nonsense change and submit it as a pull request. We are going to change the default pagination size.

First, since Vanilla Forums, Inc. uses the gitflow workflow, we need to create a branch for our patch.

git checkout 2.1
git checkout -b patch/default-pagination-update

This will create a branch called patch/default-pagination-update based on the 2.1 branch and checkout the contents into our working tree.

Open up ~/projects/vanilla/applications/vanilla/settings/configuration.php with your favorite PHP editor. Locate the line that looks like $Configuration['Vanilla']['Comments']['PerPage'] = '30'; and change the number 30 to 25. Save that file.

Now that we made a change, we need to commit that code to our git repo. You can see the status of your working tree versus the last commit by using git status. It should list the file we modified as not staged for commit. Let's stage that file and then commit it.

git add applications/vanilla/settings/configuration.php
git commit -m 'Default to 25 comments per page'

You can add all currently modified files and commit in one step using the -a switch:

git commit -a -m "Adding all modified files"

Definitely a lot faster once you are editing more than one file. That said, be careful with -a!

At this point, our local repo has our new default committed. If we want to submit this change to Vanilla Forums, Inc.'s repository, we will need to push our changes to our fork first.

git push -u

That seems easy enough.

Navigate to your repository's page on GitHub (https://github.com/{your_user_name}/vanilla if you have been following along). Select your patched branch from the branch dropdown. Then click on the compare button.

There will be a little preview with your commits below the form. If you are looking to make a PR, you will need to pick the branch you want to submit the PR to. Click edit and select the 2.1 branch on the vanilla repo. Then click on the Create Pull Request button. Fill out the form with the information of what you are trying to solve. When you are satistfied, press the Send Pull Request button.

You just submitted your first pull request!

Search first

Check out the Documentation! We are always looking for new content and pull requests.

Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

Tagged:

Comments

  • Reserved.

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • I must be crazy, but the git pull request isn't working. The latest stable release branch is release/2.2, so here's what I did:

    git checkout release/2.2 git remote add upstream git://github.com/vanilla/vanilla.git

    Then I tried the checkout/fetch/merge combo, as you suggested:

    git checkout release/2.2 git fetch upstream git merge upstream/release/2.2

    That all works great. But when I try to combine the last three commands into one, as you suggest, I type this

    git pull upstream/release/2.2

    and I get

    `fatal: 'release/2.2' does not appear to be a git repository
    fatal: Could not read from remote repository.

    Please make sure you have the correct access rights
    and the repository exists.`

    Is this the wrong syntax?

  • Also getting an issue with git push - it doesn't end up actually pushing the branch to the server, because (apparently) the default behavior of git push is to only push those branches that already exist remotely. So the actual syntax that worked for me is

    git push -u origin (branchname)

    That apparently forces the server to create the branch, and makes it so that git push works next time.

  • @MikeBattaglia You are right on both counts. I have corrected them. Thanks :)

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • rbrahmsonrbrahmson ✭✭✭

    Very insightful, thank you @hgtonight!

    I haven't yet tried to use this but already have few questions:
    1. I get the sense that while github is using a browser interface the commands you refer to in your tutorial are command line style which require memorizing the syntax. If true, is there a Windows based gui for git?
    2. You suggested to point the localhost to the downloaded project. I am using XAMPP for testing and it handles the Apache server, mysql, and vanilla in one of its subfolders. How would I be pointing it to the git project folder while still using the rest of the XAMPP setup?
    3. The tutorial assumes that the goal is to modify Vanilla, which for me may happen less often until I feel confident enough to issue PRs for Vanilla. But how should I go about:
    3.1 Creating new plugins through Github
    3.2 Suggesting PRs for existing plugins (I have something to contribute to one of your plugins)

    Appreciating your mentoring!

  • hgtonighthgtonight MVP
    edited April 2016

    @rbrahmson said:
    1. ...is there a Windows based gui for git?

    There are many. I suggest Atlassian's SourceTree as a great starting point. Not only is it well put together and helpful for learning, it also supports GitHub account integration.

    \2. How would I be pointing it to the git project folder while still using the rest of the XAMPP setup?

    You can either clone directly into your public www folder or create a symlink. I go the symlink route because I like to keep a tidy ~/projects folder, but this is not necessary.

    3.1 Creating new plugins through Github

    The easy way is to use GitHub's new repository interface, and clone it into your local machine. That automatically sets up the remote repository for you. I also have a project i use for testing out new ideas:

    git clone https://github.com/hgtonight/Plugin-TestingGround.git
    

    3.2 Suggesting PRs for existing plugins (I have something to contribute to one of your plugins)

    You fork the repository, create a branch, make your changes, and submit the pull request. I can get into more detail, but I am currently mobile.

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • rbrahmsonrbrahmson ✭✭✭

    Many thanks! Very useful and much appreciated.

  • R_JR_J Admin

    @rbrahmson: Many things can be done with the help of the web interface. For bigger changes it is more easy to use git on the command line. But for small changes, the web interface is more comfortable (into my opinion)

    Let's do something useful...

    Already logged in into my GitHub account, I take a look at one of hgtonights plugins: AutoBury
    We can safely assume it is perfect so I wouldn't be able to improve any of the existing code, but I can add something: I will add a locale file!

    In the repo I navigate to the locale folder and there I find a button "[New File]". Clicking on it opens an input box asking me for the name.
    Above that input box, there is a hint "You’re creating a file in a project you don’t have write access to. Submitting a change will create the file in a new branch in your fork R-J/Plugin-AutoBury, so you can send a pull request.". That is a very good explanation. All that you do with git on the command line is done automatically here online.

    Okay, I'll add a German locale file then: de.php. If there had been no locale folder, I would have clicked "[New File]" in the root folder of the plugin and entered "locale/de.php" as the new name.

    And below, in the "Edit new file" titled input box, I put my code:

    <?php
    $Definition['This item is buried, click to show'] = 'Hier klicken, um diesen verborgenen Eintrag wieder anzuzeigen.';
    

    Below the Input box you find a "Propose new file" section, where you can enter a "title" for your proposal and a text that you can use for longer explanations. I'll choose "Add German Language File" as a title.

    There is a green "[Propose new file]" button and clicking on it brings you to a screen full of information but with one important green button: "[Create pull request]". I click on that and again, I'm asked for a title and a text. I always choose the same (it is possible to make more than one change in one and the same pull request, so it might be that you add a file and give title and explanation for that addition, change the code of a plugin and give title and explanation for that change and then create a pull request where you summarize what you have done in title and description)

    But in my case I use the same text as before and simply press the button. hgonight gets informed via mail if he configured GitHub like that. He now can accept that PR which would make my code a part of his plugin or he can reject it.


    @hgtonight: please don't do anything of that by now.

  • R_JR_J Admin

    Darn. I wanted to show how to bundle changes to one PR, but I messed it up: GitHub is too complicated for me :lol:

    @hgtonight: you can handle the PR now. :-/

  • @R_J said:
    We can safely assume it is perfect

    :3

    @hgtonight: please don't do anything of that by now.

    Whoops, already accepted it. Now we can talk about reverting commits!

    Let's say we make a mistake. We committed buggy code. Assuming we haven't shared our commits with anyone we can amend the commit using the git commit --amend command after you have made your changes.

    If you have shared your commits with anyone (even yourself via a remote), you are best off creating a revert commit. This is a new commit that undoes exactly what a specific commit did. You use the command git revert HEAD~1.

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • R_JR_J Admin

    Now here is an example of how to make several changes to a repo with GitHub and sum it up to one PR.

    Step 1: Fork a repo

    I use hgtonights DiscussionPolls now. The way locale files have to be named has changed and that's why there has to be made a change in that plugin. If you look at the repo, you see a small gray button "[Fork]" in the upper right corner. I have clicked on it and now I have a copy of the repo as it is by now in my own repositories: "R-J/Plugin-DiscussionPolls forked from hgtonight/Plugin-DiscussionPolls".

    Step 2: Make one change

    I edit the "de" locale file, because I need to edit it in order to change its name to "../de.php". Below the title/description fields at the bottom of the bage, but above the "[Commit changes]" button, there is a radio list "Commit directly to the master branch."/"Create a new branch for this commit and start a pull request...".
    I want to commit it to master (you do not have to care what that means by now). We want to create the PR for more than one change, so "... create a pull request..." would obviously be wrong.

    Step 3: Make another change

    This time I change the Italian locale file. Same steps as above.

    Step 4: Create the pull request

    I go back to the root of my fork of the repo. There is a green "[New pull request]" available and the rest is easy like one, two, three: you see a list of changes and the next green button "[Create pull request]". Click it, add a short and a long description, click on the next green button "[Create pull request]" and it is done!

  • rbrahmsonrbrahmson ✭✭✭

    Hi guys, this is a great intro. Thanks!

  • rbrahmsonrbrahmson ✭✭✭

    OK, I got somewhere, still learning... So here is what I did:
    1. Created a fork of the Statsbox plugin
    2. Used Notepadd++ (not really integrated with SourceTree/Github - isn't there something better?) to make a change to StatsBox (the change makes the "Follows" function compatible with Vanilla 2.2 (for testing I made just one of the two necessary changes).
    2. Used SourceTree (thank you!) to push it to my forked repository.
    3. User SourceTree to commit (and gave a description).

    Now to the questions:
    1. All I did was on my forked copy. How does @hgtonigh (the plugin author) gets to know about it?
    2. Related to #1, I am not sure where to pull request goes to (my repository?)
    3. What happens when I complete the second half of the change?

  • rbrahmsonrbrahmson ✭✭✭

    typo: Related to #1, I am not sure where the pull request goes to (my repository?)

  • rbrahmsonrbrahmson ✭✭✭

    Never mind, GitHub is smarter than I am;-)... I did a PR and it went to the original source of the fork, so I assume @hgtonight will get a notification.

    Yea, my first PR!

  • rbrahmsonrbrahmson ✭✭✭

    @hgtonight wrote:

    You can either clone directly into your public www folder or create a symlink. I go the symlink route because I like to keep a tidy ~/projects folder, but this is not necessary.

    I'm not sure how to symlink in Windows XAMPP (I guess Apache), but moreover, since my main goal is plugin development (not Vanilla), the XAMPP needs access to the entire Vanilla (with a plugins directory in it). How then do I keep Vanilla in XAMPP and the few plugins I developed in there while managed in Git (SourceTree)?

  • Firstly, git repos are folders with a hidden folder inside them (.git). You can nest as many git repos as you want. You just need to take care that you do not accidentally commit nested repo source files to the parent repo.

    Windows symlinking: http://www.howtogeek.com/howto/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/

    I have used the Link Shell Extension with good results on Win 7: http://schinagl.priv.at/nt/hardlinkshellext/hardlinkshellext.html#download

    I use WAMP on windows dev boxes. It's public html folder is at C:\wamp\www. I keep my projects in my home directory C:\Users\zdoll\projects.

    1. I clone a git repo into my projects folder: git clone https://github.com/vanilla/vanilla vanilla
    2. I add a symlink to my public html folder: mklink /J C:\wamp\www\vanilla C:\Users\zdoll\projects\vanilla
    3. I can now serve the files out of the vanilla folder as if it is in my server directory (access at localhost/vanilla/)

    Note that you will have to checkout the release/2.2 branch unless you want to develop against the master branch (you probably don't want to).

    You can add symlinks within symlinked folders, so you can have your git repos in your projects directory as we;;:

    1. Clone git repo into my projects: git clone https://github.com/hgtonight/Plugin-TestingGround
    2. Symlink to my server folder: mklink /J C:\wamp\www\vanilla\plugins\TestingGround C:\Users\zdoll\projects\Plugin-TestingGround

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • rbrahmsonrbrahmson ✭✭✭

    Thank you! Very helpful and still more to learn (which is great. The only downside is that it further delays my conversion of some internally developed plugins into the public forum here, but it is well worth it). If there was a way to both mark Insightful and Awesome I'd have done that!

    Hey @linc - who said the universe has mutually exclusive choices?;-) I should be able to eat the cake and have it too!

Sign In or Register to comment.