diff --git a/docs/fixing-commits.md b/docs/fixing-commits.md new file mode 100644 index 0000000000..8efc3095dd --- /dev/null +++ b/docs/fixing-commits.md @@ -0,0 +1,33 @@ +# Fixing Commits +This is mostly from https://help.github.com/articles/changing-a-commit-message/#rewriting-the-most-recent-commit-message +## Fixing the last commit +### Changing the last commit message +1. `git commit --amend -m "New Message"` + +### Changing the last commit +1. Make your changes to the files +2. Run `git add ` to add one file or `git add ...` to add multiple files +3. `git commit --amend` + +## Fixing older commits +### Changing commit messages +1. `git rebase -i HEAD~5` (if, for example, you are editing some of the last five commits) +2. For each commit that you want to change the message, change `pick` to `reword`, and save +3. Change the commit messages + +### Deleting old commits +1. `git rebase -i HEAD~n` where `n` is the number of commits you are looking at +2. For each commit that you want to delete, change `pick` to `drop`, and save + +## Squashing commits +Sometimes, you want to make one commit out of a bunch of commits. To do this, + +1. `git rebase -i HEAD~n` where `n` is the number of commits you are interested in +2. Change `pick` to `squash` on the lines containing the commits you want to squash and save + +## Reordering commits +1. `git rebase -i HEAD~n` where `n` is the number of commits you are interested in +2. Reorder the lines containing the commits and save + +# Pushing commits after tidying them +1. `git push origin +my-feature-branch` (Note the `+` there and substitute your actual branch name.) diff --git a/docs/git-cheat-detailed.md b/docs/git-cheat-detailed.md new file mode 100644 index 0000000000..1d1923a178 --- /dev/null +++ b/docs/git-cheat-detailed.md @@ -0,0 +1,52 @@ +See also +[fixing commits](https://github.com/zulip/zulip-gci/blob/master/docs/fixing-commits.md) + +Commands: + +- add + - `git add foo.py`: add `foo.py` to the staging area + - `git add foo.py bar.py`: add `foo.py` AND `bar.py` to the staging area +- checkout + - `git checkout -b new-branch-name`: create branch `new-branch-name` and switch/checkout to that new branch + - `git checkout master`: switch to your `master` branch + - `git checkout old-branch-name`: switch to an existing branch `old-branch-name` +- commit + - `git commit --amend`: changing the last commit message. Read more [here](https://github.com/zulip/zulip-gci/blob/master/docs/fixing-commits.md) +- config + - `git config --global core.editor nano`: set core editor to `nano` (you can set this to `vim` or others) + - `git config --global core.symlinks true`: allow symbolic links +- diff + - `git diff`: display the changes you have made to all files + - `git diff --cached`: display the changes you have made to staged files + - `git diff HEAD~2..`: display the 2 most recent changes you have made to files +- fetch + - `git fetch origin`: fetch origin repository + - `git fetch upstream`: fetch upstream repository +- grep + - `git grep update_unread_counts -- '*.js'`: search all files (ending in `.js`) for `update_unread_counts` +- log + - `git log`: show commit logs +- pull + - **do not use for Zulip** +- push + - `git push origin +branch-name`: push your commits to your origin repository +- rebase + - `git rebase -i HEAD~3`: interactive rebasing current branch with first three items on HEAD + - `git rebase -i master`: interactive rebasing current branch with master branch + - `git rebase upstream/master`: rebasing current branch with master branch from upstream repository +- reflog + - `git reflog | head -10`: manage reference logs for the past 10 commits +- remote + - `git remote -v`: display your origin and upstream repositories +- reset + - `git reset HEAD~2`: reset two most recent commits +- rm + - `git rm oops.txt`: remove `oops.txt` +- show + - `git show HEAD`: display most recent commit + - `git show HEAD~~~`: display third most recent commit + - `git show master`: display most recent commit on `master` +- status + - `git status`: show the working tree status, unstaged and staged files + + diff --git a/docs/git-cheat-sheet.md b/docs/git-cheat-sheet.md new file mode 100644 index 0000000000..5b845a4de6 --- /dev/null +++ b/docs/git-cheat-sheet.md @@ -0,0 +1,51 @@ +See also +[fixing commits](https://github.com/zulip/zulip-gci/blob/master/docs/fixing-commits.md) + +Commands: + +- add + - `git add foo.py` +- checkout + - `git checkout -b new-branch-name` + - `git checkout master` + - `git checkout old-branch-name` +- commit + - `git commit --amend` +- config + - `git config --global core.editor nano` + - `git config --global core.symlinks true` +- diff + - `git diff` + - `git diff --cached` + - `git diff HEAD~2..` +- fetch + - `git fetch origin` + - `git fetch upstream` +- grep + - `git grep update_unread_counts -- '*.js'` +- log + - `git log` +- pull + - **do not use for Zulip** +- push + - `git push origin +branch-name` +- rebase + - `git rebase -i HEAD~3` + - `git rebase -i master` + - `git rebase upstream/master` +- reflog + - `git reflog | head -10` +- remote + - `git remote -v` +- reset + - `git reset HEAD~2` +- rm + - `git rm oops.txt` +- show + - `git show HEAD` + - `git show HEAD~~~` + - `git show master` +- status + - `git status` + + diff --git a/docs/images/shell-screenshot.png b/docs/images/shell-screenshot.png new file mode 100644 index 0000000000..cda46476b8 Binary files /dev/null and b/docs/images/shell-screenshot.png differ diff --git a/docs/shell-tips.md b/docs/shell-tips.md new file mode 100644 index 0000000000..a4fc3483c3 --- /dev/null +++ b/docs/shell-tips.md @@ -0,0 +1,335 @@ +# Shell tips + +The *shell* is a **command line interpreter**. To use it you can open a +*terminal* (sometimes called a *console*). This is how most terminal windows +look like: + +![An example shell window](shell-screenshot.png) + +If you haven't used it before, you should probably take a look at +[this tutorial](http://linuxcommand.org/lc3_learning_the_shell.php). + +If you're using Windows, +[these videos](https://www.youtube.com/playlist?list=PL6gx4Cwl9DGDV6SnbINlVUd0o2xT4JbMu) +may be useful too, but keep in mind that the following tips only apply to +Linux/macOS environments (Unix shells). You can also use a tool, for example +[Cygwin](https://www.cygwin.com/), to have a Unix-like shell on Windows. + +## The prompt (`$`) + +When searching Google, or Zulip's docs, you'll find commands that begin +with a dollar sign `$` or a dollar sign preceded by some text +(e.g. `(venv)john@laptop:~$`). + +This is called the **prompt**, and it's only an indicator that the shell is +awaiting new orders. The prompt can contain useful information, let's look +at `(venv)john@laptop:~$`: + +- `(venv)` informs the user that they're currently in a virtual environment +(more on [Python virtual + environments](http://docs.python-guide.org/en/latest/dev/virtualenvs/)) +- the `john` before `@` is the username +- the `laptop` is the host machine name +- the `~` after the colon informs the user they're currently in the home +folder of the user `john` + +You shouldn't type the prompt or the text preceding it, since it isn't a +part of the commands. + +## Tilde character (`~`) + +It's very frequent to see the tilde (`~`) in paths. The tilde is an +abbreviation for your home directory (`/home/YOUR_USERNAME` most of the times). + +That's why the following is exactly the same, if the user running it is +`john`: + +``` +$ cd ~ +$ cd /home/john +``` + +## Change directory (`cd`) + +When you're using the shell, you work inside a directory (the one specified in +the prompt). This way you can point to files relative to your current +directory, instead of writing the whole path. + +Imagine you have a file called `ideas.txt` inside `/home/john/notes/`, and +you want to edit it using `nano`. You could use: + +``` +$ nano /home/john/notes/ideas.txt +``` + +However, that isn't very practical, especially if you are working with +longer paths. + +That's why it's very useful to change the path where you are currently +located (usually known as **working directory**). To do that, you use `cd` +(**c**hange **d**irectory): + +``` +$ cd /home/john/notes/ +~/notes$ nano ideas.txt +``` + +Or, if you're the user `john`: `cd ~/notes`. + +You can now access to all the files inside `/home/john/notes` directly, without +needing to type the whole path. + +[Relative paths](http://www.linuxnix.com/abslute-path-vs-relative-path-in-linuxunix/) +make it much easier to move through files and directories, too. + +## Running commands as root (`sudo`) + +You may have noticed that many commands begin with `sudo`. This informs the +shell that the following command must be run as the root - a user that by +default has access to all commands and files on a Unix operating system (i.e. +a user with administrator privileges). That's why you may be asked for a +password in those cases: the system verifies you have permission to act as +the *root* user. + +In case you were wondering, the name `sudo` comes from **s**uper **u**ser +**do**. + +## Escaping characters + +Some characters cannot be used directly in the shell, because they have a +special meaning. Consider the following example: + +``` +$ echo "He said hello" +He said hello +``` + +What if you wanted to display double quotes? You can't use +`echo "He said "hello""`, because in that case you're using the +double quotes for two different purposes: + +- Delimiting the string you want to use, from `He` to `"hello"`. +- Quoting something, by literally printing `"`. + +You have to specify which double quotes are used in each case. When you want +one of those "special characters" to be literally printed, that's called +**character escaping**. To escape a character, simply add a backslash (`\`) +before it. + +Returning to our example: + +``` +$ echo "He said \"hello\"" +He said "hello" +``` + +As you can see, the double quotes with the backslash are shown, but the ones +without it are used as string delimiters. + +Double quotes aren't the only case of special characters. Some others are `$`, +`#`, `{` or `}`, but there are many more. The backslash itself can be escaped +as well, using the same procedure: `\\`. + +## Sequencing commands + +It's also possible to run multiple commands in a single line. For that purpose, +the shell provides two different separators: + +- **Semicolon `;`**: runs a command, and once it has finished, runs the next + one: + + ``` + $ echo "Hello"; echo "World!" + Hello + World! + ``` + +- **Double ampersand `&&`**: runs a command, and **only if** it finished + without errors, it proceeds with the next one: + + ``` + $ qwfvijwe && echo "Hello" + qwfvijwe: command not found + ``` + + Notice that it doesn't print `Hello` at the end, because the previous + command (`qwfvijwe`) returned an error. + + When using an incorrect command with a semicolon, the `Hello` will still + be printed: + + ``` + $ qwfvijwe; echo "Hello" + qwfvijwe: command not found + Hello + ``` + +## Splitting commands into multiple lines + +Sometimes you end up with a very long command, that is hard to read and may +be unclear. This is a problem, especially if you want to share that command, +e.g. in a documentation file. + +In those cases, you can use a backslash at the end of each line, to inform the +shell "wait, there's more on the next line". + +This is an example, taken from the docs on how to install the Zulip development +environment: + +``` +sudo apt-get -y purge vagrant && \ +wget https://releases.hashicorp.com/vagrant/1.8.6/vagrant_1.8.6_x86_64.deb && \ +sudo dpkg -i vagrant*.deb && \ +sudo apt-get -y install build-essential git ruby lxc lxc-templates cgroup-lite redir && \ +vagrant plugin install vagrant-lxc && \ +vagrant lxc sudoers +``` + +It's all a single command, joined using the double ampersand explained in +[Sequencing commands](#sequencing-commands). If you're typing it manually, +you don't need to include the backslashes, just write it all on the same line, +and hit ENTER/RETURN at the end. + +If you think about it, what is happening here is actually another case of +character escaping. The newline character (the one that appears when you hit +ENTER) usually means "read this command". However, here we want to +literally have the newline character, and thus the `\`. + +The newline character is invisible (we only see a line break), but it's still +there! + +## Arguments + +Most commands need additional data to work, like a path or a file. That extra +information is called an **argument**, and it's specified after the name of the +command, like this: + +``` +$ cd /home/john/notes +``` + +Here, the command is `cd`, and the first (and only) argument is +`/home/john/notes`: + +- `cd` - *command*: changes your current directory. + +- `/home/john/notes` - *argument*: the directory where you want to go. + +In each command the arguments are specified in different ways, and have +different meanings. + +Sometimes, a command can accept arguments indicated with dashes. Here's another +example of arguments usage: + +``` +$ nano -C /home/john/backups --mouse todo.txt +``` + +As you can see, some arguments imply that more information has to be specified, +while others don't. + +In this case, we're saying: "Bash, use the app `nano` to open the file +`todo.txt`, enabling mouse support, and saving the backup files to +`/home/john/backups`". The different parts are: + +- `nano` - *command*: program that allows editing text easily. + +- `-C` - *argument*: needs you to indicate where the backups should be stored, + and thus you have to add an additional argument after it, to specify the + directory (`/home/john/backups` in the example). + +- `--mouse` - *argument*: is just an option you set, `nano` doesn't need + anything else to make it work. Thus, there isn't any extra argument for that. + +Note that the `todo.txt` is the file we want to open! It has nothing to do with +the previous argument. This will probably clarify it (taken from `nano`'s +help): + +``` +Usage: nano [OPTIONS] [FILE]... +``` + +So, in the options you indicate the arguments, and `FILE` is... well, the file. + +Don't worry, you don't have to memorize the meaning of +all the arguments for every single command. There are +[tools](#understanding-commands) that help you with that :wink:. + +## Shebang + +You can run some files directly, without specifying a program to interpret +them. + +That's why you may have seen cases when some Python scripts are called with +`python`: + +``` +$ python my_program.py +``` + +While other times, `python` isn't used: + +``` +$ ./my_program.py +``` + +In the latter, it's skipped because `my_program.py` already specifies in it +which interpreter should be used (in this case, `python`). + +This is indicated in the very first line of the script files, and it's called +a **shebang**. In Python scripts, it looks like this: + +``` +#!/usr/bin/env python +``` + +With this, you're telling the shell: "if I tell you to run this, ask +`/usr/bin/env python` how to understand it". + +`/usr/bin/env` is a way to identify where `python` is installed. If it was in +`/usr/bin/python`, you could use the shebang `#!/usr/bin/python`, but `env` +allows more flexibility (since not everyone has their Python interpreter +there). + +Another example of shebang is the one used in Bash scripts. In those cases, +`#!/bin/sh` is used. + +The result is that the shell calls the program specified in the shebang, with +the script as a parameter. So, returning to our example with `my_program.py`, +when you run `./my_program.py`, what happens under the hood is: + +``` +$ /usr/bin/env python my_program.py +``` + +## Understanding commands + +Frequently, you may find commands that you don't understand, or don't +know what they do. You can use `man ` to see the **man**ual page for +that specific command. Also, you may find useful +[explainshell](http://explainshell.com/), a webpage that explains what most +commands do, part by part. + +## Cheatsheet + +There are many more commands in the shell, besides the ones explained in this +file. +[Here](https://www.git-tower.com/blog/command-line-cheat-sheet/) you can find +a simple yet useful cheatsheet, created by Tower, that could help you +understand and remember what other common commands do (e.g. `ls`). + +## Git + +Probably at this point you've heard about Git. It's basically a tool that most +developers use to manage all the changes in their code. + +At first it seems like magic, but once you get the basic concepts you find it +extremely useful and even easy to use (at least the 99% of the time). + +To learn more about how to use it, read +[our docs](http://zulip.readthedocs.io/en/latest/git-guide.html) on Git and +Github. +[This cheatsheet](https://github.com/zulip/zulip-gci/blob/master/docs/git-cheat-detailed.md) +will be useful in your journey, as well. + +![Git - XKCD 1597](https://imgs.xkcd.com/comics/git.png) diff --git a/docs/working-copies.md b/docs/working-copies.md new file mode 100644 index 0000000000..c58858be2c --- /dev/null +++ b/docs/working-copies.md @@ -0,0 +1,54 @@ +## Intro + +When you work on Zulip code, there are three working copies +of the Zulip git repo that you are generally concerned with: + +- local copy: This lives on your laptop or your remove dev instance. +- forked copy: This lives on GitHub, and it's tied to your account. +- official Zulip repo: https://github.com/zulip/zulip + +We sometimes call the forked copy the **origin** remote. + +We sometimes call the official repo the **upstream** remote. + +When you work on Zulip code, you will end up moving code between +the various working copies. + +## Workflows + +Sometimes you need to get commits. Here are some scenarios: + +- You may fork the official Zulip repo to your Github fork. +- You may fetch commits from the offical Zulip repo to your local copy. +- You occasionally may fetch commits from your forked copy. + +Sometimes you want to publish commits. Here are scenarios: + +- You push code from your local copy to your Github fork. (You usually + want to put the commit on a feature branch.) +- You submit a PR to the official Zulip repo. + +Finally, the Zulip core team will occasionally want your changes! + +- The Zulip core team can accept your changes and add them to + the official repo, usually on the master branch. + +## Names + +We call remote working copies of the repository by these short +names. + +- **origin**: This is your fork. +- **upstream**: This is the official Zulip repo. + +## Relevant git commands + +The following commands are useful for moving commits between +working copies: + +- `git fetch`: This grabs code from another repo to your local copy. +- `git push`: This pushes code from your local repo to one of the remotes. +- `git remote`: This helps you configure short names for remotes. (Your + mentor can help you with this.) +- `git pull`: **Do not use this, please**! +