---
title: "Basic Git Workflow"
---

> Documentation Index
> Fetch the complete documentation index at: https://contribute.freecodecamp.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Basic Git Workflow

Follow these guidelines to contribute to the codebase. This is highly recommended if you want to contribute regularly.
Ignoring these steps may soil your copy which makes the contributing, maintaining, and reviewing processes difficult.

## Contributing to the Codebase

You can now make changes to files and commit your changes to your fork, which you can prepare by reading [how to set up freeCodeCamp locally](/how-to-setup-freecodecamp-locally/).

Follow these steps:

1. Validate that you are on the `main` branch:

   ```bash
   git status
   ```

   You should get an output like this:

   ```bash
   On branch main
   Your branch is up-to-date with 'origin/main'.

   nothing to commit, working directory clean
   ```

   If you got a different message, then you aren't on main or your working directory isn't clean, resolve any outstanding files/commits and checkout `main`:

   ```bash
   git checkout main
   ```

   If you get a message similar to this one:

   ```bash
   On branch feat/colour-picker
   Changes not staged for commit:
     (use "git add <file>..." to update what will be committed)
     (use "git restore <file>..." to discard changes in working directory)
        modified:   curriculum/i18n-curriculum (new commits)
   ```

   Then the i18n curriculum submodule is out of sync. You should NOT commit changes to the submodule through our main repository. Instead, to resolve this, run:

   ```bash
   git submodule update --init
   ```

2. Sync the latest changes from the freeCodeCamp upstream `main` branch to your `main` fork branch:

   :::caution
   If you have any outstanding pull requests that you made from the `main` branch of your fork, you will lose them at the end of this step.

   You should ensure your pull request is merged by a moderator before performing this step. To avoid this scenario, you should **always** work on a branch other than the `main`.

   :::

   This step **will sync the latest changes** from the main repository of freeCodeCamp.

   Update your copy of the freeCodeCamp upstream repository:

   ```bash
   git fetch upstream
   ```

   Hard reset your main branch with the freeCodeCamp main:

   ```bash
   git reset --hard upstream/main
   ```

   Push your main branch to your origin to have a clean history on your fork on GitHub:

   ```bash
   git push origin main --force
   ```

   You can validate that your current main matches the upstream/main by performing a diff:

   ```bash
   git diff upstream/main
   ```

   The resulting output should be empty. This process is important, because you will be rebasing your branch on top of the latest `upstream/main` as often as possible to avoid conflicts later.

3. Create a fresh new branch:

   Working on a separate branch for each issue helps you keep your work copy clean. You should never work on the `main`. This will soil your copy of freeCodeCamp and you may have to start over with a fresh clone or fork.

   Check that you are on `main` as explained previously, and branch off from there:

   ```bash
   git checkout -b fix/update-guide-for-xyz
   ```

   Your branch name should start with a `fix/`, `feat/`, `docs/`, etc. Avoid using issue numbers in branches. Keep them short, meaningful and unique.

   Some examples of good branch names are:

   ```md
   fix/update-challenges-for-react
   fix/update-guide-for-html-css
   fix/platform-bug-sign-in-issues
   feat/add-guide-article-for-javascript
   translate/add-spanish-basic-html
   ```

4. Edit pages and work on code in your favorite text editor.

5. Once you are happy with the changes you should optionally run freeCodeCamp to preview the changes.

6. You should run any relevant test commands. For example, if you have edited a challenge; you should run a command to test that challenge.

7. Make sure you fix any errors and check the formatting of your changes.

8. Check and confirm the files you are updating:

   ```bash
   git status
   ```

   This should show a list of `unstaged` files that you have edited.

   ```bash
   On branch feat/documentation
   Your branch is up to date with 'upstream/feat/documentation'.

   Changes were not staged for commit:
   (use "git add/rm <file>..." to update what will be committed)
   (use "git checkout -- <file>..." to discard changes in the working directory)

       modified:   CONTRIBUTING.md
       modified:   docs/README.md
       modified:   docs/how-to-setup-freecodecamp-locally.md
       modified:   docs/how-to-work-on-guide-articles.md
   ...
   ```

9. Stage the changes and make a commit:

   In this step, you should only mark files that you have edited or added yourself. You can perform a reset and resolve files that you did not intend to change if needed.

   ```bash
   git add path/to/my/changed/file.ext
   ```

   Or you can add all the `unstaged` files to the staging area:

   ```bash
   git add .
   ```

   Only the files that were moved to the staging area will be added when you make a commit.

   ```bash
   git status
   ```

   Output:

   ```bash
   On branch feat/documentation
   Your branch is up to date with 'upstream/feat/documentation'.

   Changes to be committed:
   (use "git reset HEAD <file>..." to unstage)

       modified:   CONTRIBUTING.md
       modified:   docs/README.md
       modified:   docs/how-to-setup-freecodecamp-locally.md
       modified:   docs/how-to-work-on-guide-articles.md
   ```

   Now, you can commit your changes with a short message like so:

   ```bash
   git commit -m "fix: my short commit message"
   ```

   Some examples:

   ```md
   fix: add test for JavaScript - for loop step
   feat: add link for article for alexa skills
   ```

   Make a conventional commit message. This is a good practice as a developer, and you will be following standard practices.

   Some examples of conventional commit messages are:

   ```md
   fix: improve HTML step
   fix: fix build scripts for Travis-CI
   feat: add link to JavaScript hoisting article
   docs: update contributing guidelines
   ```

   Keep these short, not more than 50 characters. You can always add additional information in the description of the commit message.

   This does not take any more time than an unconventional message like 'update file' or 'add index.md'

   You can learn more about why you should use conventional commits [here](https://www.conventionalcommits.org/en/v1.0.0-beta.2/#why-use-conventional-commits).

10. If you realize that you need to edit a file or update the commit message after making a commit you can do so after editing the files with:

    ```bash
    git commit --amend
    ```

    This will open up a default text editor like `nano` or `vi` where you can edit the commit message title and add/edit the description.

11. Next, you can push your changes to your fork:

    ```bash
    git push origin branch/name-here
    ```

:::caution
Do not repeatedly merge the `main` branch into your feature branch. Every merge commit triggers another round of CI runs that we have to pay for, and it clutters your pull request history. When you need to update your branch with the latest changes from `upstream/main`, [rebase](https://git-scm.com/book/en/v2/Git-Branching-Rebasing) instead. Also make sure your existing commits are squashed into a small set of meaningful commits before opening (or updating) your pull request.
:::

## Proposing a Pull Request (PR)

After you've committed your changes, check here for [how to open a Pull Request](/how-to-open-a-pull-request/).

## Quick commands reference

A quick reference to the commands that you will need when working.

| command                                                                  | description                                                                  |
| ------------------------------------------------------------------------ | ---------------------------------------------------------------------------- |
| `pnpm develop`                                                           | Build and develop the full freeCodeCamp codebase.                            |
| `pnpm test`                                                              | Run all the test suites.                                                     |
| `pnpm test-client`                                                       | Run the client test suite.                                                   |
| `pnpm test-client --only -- -u`                                          | Run the client test suite, updating the Jest snapshots that are out of sync. |
| `pnpm test-curriculum-content`                                           | Run the curriculum test suite.                                               |
| `FCC_CHALLENGE_ID=646cf6cbca98e258da65c979 pnpm test-curriculum-content` | Test a specific Challenge.                                                   |
| `FCC_BLOCK='basic-html-and-html5' pnpm test-curriculum-content`          | Test a specific Block.                                                       |
| `FCC_SUPERBLOCK='responsive-web-design' pnpm test-curriculum-content`    | Test a specific SuperBlock.                                                  |
| `pnpm test-api`                                                          | Run the server test suite.                                                   |
| `pnpm playwright:run`                                                    | Run the Playwright end to end tests.                                         |
| `FCC_CHALLENGE_ID=646cf6cbca98e258da65c979 pnpm run develop`             | Build and develop a specific Challenge.                                      |
| `FCC_BLOCK='basic-html-and-html5' pnpm run develop`                      | Build and develop a specific Block.                                          |
| `FCC_SUPERBLOCK='responsive-web-design' pnpm run develop`                | Build and develop a specific SuperBlock.                                     |
| `pnpm run clean`                                                         | Uninstalls all dependencies and cleans up caches.                            |

## Speeding up your workflows (applies to fCC Staff only)

We make use of turborepo for caching and parallelizing tasks. To take advantage of the remote cache, add the following variables to your `.env` file `TURBO_API`, `TURBO_TEAM`, `TURBO_TOKEN`, `TURBO_REMOTE_CACHE_SIGNATURE_KEY` and `TURBO_CACHE`. These values are in Turborepo Remote Cache in 1password.

The easiest way to do this to make use of [direnv](https://direnv.net/). After installing it, it needs [configuring](https://direnv.net/man/direnv.toml.1.html#description) with

```toml
[global]
load_dotenv = true
```

typically in `~/.config/direnv/direnv.toml`.

Source: https://contribute.freecodecamp.org/basic-git-workflow/index.mdx
