# Git & GitHub Tips

### Add Upstream Remote to Our Forked Git Repos

Assuming we have forked the repo.

Now we clone our forked repo:

```
$ git clone git@github.com:YOUR-USERNAME/THE-REPO.git
```

See what remotes we have:

```
$ git remote -vv
origin	git@github.com:YOUR-USERNAME/THE-REPO.git (fetch)
origin	git@github.com:YOUR-USERNAME/THE-REPO.git (push)
```

To add the upstream remote:

```
$ git remote add upstream git://github.com/UPSTREAM-USERNAME/THE-REPO.git
$ git remote -vv
origin	git@github.com:YOUR-USERNAME/THE-REPO.git (fetch)
origin	git@github.com:YOUR-USERNAME/THE-REPO.git (push)
upstream	git@github.com:UPSTREAM-USERNAME/THE-REPO.git (fetch)
upstream	git@github.com:UPSTREAM-USERNAME/THE-REPO.git (push)
```

### Syncing a fork

1. Fetch the branches and their respective commits from the upstream repository.

Commits to `master` will be stored in a local branch, `upstream/master`.

```
$ git fetch upstream
```

1. Check out your fork's local `master` branch.

```
$ git checkout master
```

1. Merge the changes from `upstream/master` into your local `master` branch.

This brings your fork's master branch into sync with the upstream repository, without losing your local changes.

```
$ git merge upstream/master

$ git status
On branch master
Your branch is ahead of 'origin/master' by 4 commits.
  (use "git push" to publish your local commits)
```

If you just want to sync up without local changes, you may push it after `git merge`:

```
$ git push

$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean
```

### Check What's Going to be Pushed?

For a list of files to be pushed, run:

```
$ git diff --stat --cached [remote/branch]
```

### How to Delete Local and/or Remote Branch?

```
$ git push --delete <remote_name> <branch_name>
$ git branch -d <branch_name>
```

### To Contribute Multiple PRs?

Better use a dedicated branch for one PR, like below.

For PR-1:

```
$ git checkout master
$ git checkout -b pr-1
...work, work, work
$ git add xxx
$ git commit -am "add pr-1"
$ git push origin pr-1
```

Now there is another PR-2 you want to do, while waiting for the PR-1 to be accepted and merged:

```
$ git checkout master
$ git checkout -b pr-2
...work, work, work
$ git add xxx
$ git commit -am "add pr-2"
$ git push origin pr-2
```

### How to "Rollback" the versions of one specific file?

```
$ git checkout master~2 ThatFile.ext
$ git commit -m "revert back" ThatFile.ext
$ git push
```

### `git push --set-upstream origin master` but somehow the old user is being used?

```
$ git push --set-upstream origin master
remote: Permission to brightzheng100/xxx.git denied to <ANOTHER/OLD USER>.
```

If you checked through `git config --global -l` or `cat ~/.gitconfig` but same issue remains, it's most likely caused by **OSX Keychain**. Resolve it by following below steps:

1. In Finder, search for the `Keychain Access app`
2. In Keychain Access, search for `github.com`
3. GitHub Password Entry in KeychainFind the "internet password" entry for `github.com`
4. Edit or delete the entry accordingly.

### Merge PR With Conflicts

```
# start from master branch
git checkout master

# checkout a new branch
git checkout -b pr-merging

# add the PR in as a remote
git remote add pr-agregory999 https://github.com/agregory999/platform-automation-pipelines.git
# fetch the content
git fetch pr-agregory999
# check it out as a local branch
git checkout --track pr-agregory999/master -b pr-agregory999

# rebase pr-merging so both have same ancestor
git rebase pr-merging

# work work work
<WORK ON CONFLICTS...>
<ADD/EDIT/DELETE FILES...>

# add all changes as one shot & commit
git add .
git commit -am "Merge pull request #3 from agregory999/master"

# checkout to pr-merging and merge it
git checkout pr-merging
git merge --no-ff --log -m "Merge PR #3 from agregory999/master" pr-agregory999

# checkout master
git checkout master

# merge pr-merging with --squash
git merge --squash pr-merging

# now all changes will be displayed
git status
On branch master
Your branch is up to date with 'origin/master'.

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

	modified:   README.md
	new file:   ops-files/resource-gcs.yml
	modified:   vars-dev/vars-common.yml
	modified:   vars-pez/vars-common.yml

# add all changes in and commit
git add .
git commit -am "Merge pull request #3 from agregory999/master"

# push it
git push


#######clean up##########

git branch -D pr-agregory999
git branch -D pr-merging
git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean
```

### Ref

1. <https://help.github.com/articles/syncing-a-fork/>
2. <https://stackoverflow.com/questions/3636914/how-can-i-see-what-i-am-about-to-push-with-git>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://brightzheng100.gitbook.io/tech-diary/devops/git-and-github-tips.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
