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:

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.

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.

Comments

What is GitHub?

GitHub is a web service that hosts git repositories (repos for short). git is a distributed version control system that is designed for collaboration. So, GitHub hosts a git repository.

Vanilla Forums, Inc. uses GitHub to host the source code for Vanilla.

They want you to submit issues and patches through GitHub.

What is a Version Control System?

A version control system, or VCS, is used to keep track of code changes. Most VCSs provide committing, branches, and merging. I explain each feature briefly below.

As you code up features in your software, you periodically save your progress in the VCS. In git, this is called committing code. A major benefit of committing code is being able to roll back changes if you mess something up.

As you start releasing software, you may want to manage multiple versions of code simultaneously. In git, these different versions are called branches. Any commits you make to one branch are not automatically shared with the other branches.

As you find bugs in your code, you probably want to fix them. Once you commit your changes to fix the bug, you probably want to also fix it in another branch. While you could create a separate patch and commit it to that branch, you can instead merge two branches together. This will take all of the commits from one branch and apply them another branch.

Why use git?

git is a distributed version control system. Apart from just being a version control system, it is designed to be used by multiple people simultaneously. Everyone can commit their changes independently of each other.

GitHub hosts git repositories. Vanilla Forums, Inc. hosts their repos there. This gives anyone with a knowledge of git to have direct access to the source code. This is a huge advantage for open source projects.

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.

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)

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.

@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.

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.

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.

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!

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?

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.

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!