mirror of https://github.com/zulip/zulip.git
docs: Move GCI docs into main repo.
This commit is contained in:
parent
15b058121f
commit
f880ee4ba0
|
@ -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 <filename>` to add one file or `git add <filename1> <filename2> ...` 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.)
|
|
@ -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
|
||||
|
||||
|
|
@ -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`
|
||||
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -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 <kbd>ENTER</kbd>/<kbd>RETURN</kbd> 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
|
||||
<kbd>ENTER</kbd>) usually means "read this command". However, here we want to
|
||||
literally have the newline character, and thus the `\<newline>`.
|
||||
|
||||
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 <command>` 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)
|
|
@ -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**!
|
||||
|
Loading…
Reference in New Issue