資訊系必備的版本管理工具
what is Git
Cloud
You
Cloud
Push
You
Repository
Cloud
Push
You
Repository
Cloud
You
Repository
Friend
Clone
Cloud
You
Repository
Friend
Push
Cloud
You
Repository
Friend
Pull
GitHub
You
Git
Git
誰說資訊系不用GUI?
官網:https://www.sublimemerge.com
Ctrl + p
關於自己做事
創建倉庫 / 環境設定
選單 > File > New Repository
~/.gitconfig
影響所有 repo
<repo>/.git/config
目前所在 repo
放上卡車 / 檢查卡車 / 送進倉庫
git add
modified
untracked
staged
modified
staged
git commit
commit message
a.txt
並放入卡車git init / config / add / status / commit
git init
git config
git add
git status
git commit
$ git init
$ git init <repo_name>
$ git config [--global] user.name "<your_name>"
$ git config [--global] user.email "<your_email>"
$ git add a.txt
$ git add *.c
$ git add .
$ git add --all
$ git status
modified
untracked
staged
$ git commit
$ git commit -m "<message>"
$ git status
$ git commit
請養成 commit 前檢查 status 的好習慣
$
指令 time
git restore / rm
git add
某些檔案Task: 創建並讓 b.txt
在 staged 跟 modified 間反覆橫跳移動
git restore / rm
$ git restore --staged a.txt
$ git restore --staged *.c
a.txt
並放入 staging area哭阿
git restore
是以 commit 為基底進行復原$ git rm --cached a.txt
$ git rm --cached *.c
--cached:
改成變為 untracked$ git restore a.txt
$ git restore [--staged] <file>
$ git rm [--cached] <file>
$
指令 time
查看歷史 / 刪除歷史 / 暫存桌面 / 回到過去
git add
git commit
git log
長很醜soft
:改成 stagedmixed
:改成 modifiedhard
:直接刪除mixed
結果git reset --hard
是一個十分危險的指令,一旦使用所有進度都會直接消失。請勿搭配酒精使用,並確認無誤再下達。
stage all
stash
pop
stash
清空桌面pop
之後取回把桌面清空 回到第一個 commit 再回來並回復桌面
git log
git reset
git stash
git checkout
$ git log
$ git reset <commit_ID>
$ git reset --soft <commit_ID>
$ git add --all
$ git stash
只會暫存 staging area
$ git stash pop
$ git checkout <commit_ID>
$ git checkout master
git checkout
$
指令 time
.gitignore
secret_key.txt
a.exe a.out
.vscode/ .DS_Store
a.txt~ b.txt.swp
git add --all
git status
很醜.gitignore
.gitignore"
git status / add
看到.gitignore
secret_key.txt
*.exe
*.out
.vscode/
.DS_Store
*~
*.swp
$ vim .gitignore
.gitignore
可以每個資料夾底下都放一個git rm --cached <file>
變回 untrackedTask: 撰寫 .gitignore
使 git 無法追蹤 secret_key.txt
$ git checkout break_time !
關於分工合作
A
B
b
A
B
E
C
D
F
G
branch
merge
b
e
c
f
d
g
branch:分化出不同的分支完成不同的部分
merge:將不同分支的內容整合在一起
A
git checkout main
B
main
A
git checkout main
git commit -m "C"
B
C
main
A
git checkout main
git commit -m "C"
git commit -m "D"
B
C
main
D
A
git checkout main
git commit -m "C"
git commit -m "D"
git checkout <commit ID of B>
B
C
HEAD
main
D
A
git checkout main
git commit -m "C"
git commit -m "D"
git checkout <commit ID of B>
git checkout -b dev
B
C
dev
main
D
A
git checkout main
git commit -m "C"
git commit -m "D"
git checkout <commit ID of B>
git checkout -b dev
git commit -m "E"
B
C
dev
main
D
E
A
git checkout main
git commit -m "C"
git commit -m "D"
git checkout <commit ID of B>
git checkout -b dev
git commit -m "E"
git checkout main
B
C
dev
main
D
E
A
git checkout main
git commit -m "C"
git commit -m "D"
git checkout <commit ID of B>
git checkout -b dev
git commit -m "E"
git checkout main
git commit -m "F"
B
C
dev
main
D
E
F
A
git checkout main
git commit -m "C"
git commit -m "D"
git checkout <commit ID of B>
git checkout -b dev
git commit -m "E"
git checkout main
git commit -m "F"
git checkout dev
B
C
dev
main
D
E
F
A
git checkout main
git commit -m "C"
git commit -m "D"
git checkout <commit ID of B>
git checkout -b dev
git commit -m "E"
git checkout main
git commit -m "F"
git checkout dev
git commit -m "G"
B
C
dev
main
D
E
F
G
main
main
dev
main
dev
main
dev
int stack[100], top = 0;
void push(int x){
}
int pop(int x){
}
int stack[100], top = 0;
void push(int x){
stack[top++] = x;
}
int pop(){
}
int stack[100], top = 0;
void push(int x){
}
int pop(){
return stack[--top];
}
int stack[100], top = 0;
void push(int x){
stack[top++] = x;
}
int pop(){
return stack[--top];
}
A
git checkout main
B
C
dev
main
D
E
F
D
F
A
git checkout main
git merge dev
B
C
dev
main
D
E
F
G
G
main
dev
main
dev
?
兩邊對相同的地方做不同的修改
Git 無法自動判斷哪邊該留下
需要手動合併
int gcd(int a, int b){
<<<<<<< HEAD
while(b != 0){
int tmp = b;
b = a % b;
a = tmp;
}
return a;
=======
return a % b == 0
? b
: gcd(b, a % b);
>>>>>>> rec
}
int gcd(int a, int b){
}
int gcd(int a, int b){
while(b != 0){
int tmp = b;
b = a % b;
a = tmp;
}
return a;
}
int gcd(int a, int b){
return a % b == 0
? b
: gcd(b, a % b);
}
int gcd(int a, int b){
return a % b == 0
? b
: gcd(b, a % b);
}
<<<<<<< HEAD
合併前的檔案內容
=======
合併進來的分支的檔案內容
>>>>>>> 合併進來的分支名稱
關於異地同步
push & pull
pull
push
「嘿,現在的版本樹長怎樣」
「嘿,我做了某某某修改」
for synchronization
A
B
dev
main
C
D
E
F
A
B
dev
main
C
D
E
A
B
dev
main
C
D
E
F
git fetch
A
B
dev
main
C
D
E
F
A
B
dev
main
C
D
E
A
B
origin/dev
origin/main
C
D
E
F
git fetch
git merge
A
B
dev
main
C
D
E
F
A
B
dev
main
C
D
E
A
B
origin/dev
origin/main
C
D
E
F
= git pull
A
B
dev
main
C
D
E
F
A
B
dev
main
C
D
E
G
origin/dev
A
B
main
dev
C
D
E
F
main
C
dev
G
A
B
origin/main
C
D
E
F
A
B
main
C
D
E
F
main
C
G
A
B
origin/main
C
D
E
F
H
dev
dev
origin/dev
for contribution
A
B
dev
main
C
D
E
A
B
dev
main
C
D
E
F
A
B
dev
main
C
D
E
F
A
B
main
C
D
E
A
B
dev
main
C
D
E
F
git push origin dev
A
B
dev
main
C
D
E
F
git push origin dev
A
B
main
C
D
E
F
dev
A
B
main
dev
C
D
E
G
To github.com:username/reponame.git
! [rejected] dev -> dev (fetch first)
error: failed to push some refs to 'github.com:username/reponame.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
E
F
origin/dev
G
dev
H
E
F
origin/dev
G
dev
E
F
dev
pull
merge
push
E
G
dev
E
F
G
dev
H
> git push origin dev
To github.com:username/reponame.git
! [rejected] dev -> dev (fetch first)
error: failed to push some refs to 'github.com:username/reponame.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
> git pull
...
Auto-merging <filename>
CONFLICT (content): Merge conflict in <filename>
Automatic merge failed; fix conflicts and then commit the result.
> git add .
> git commit -m "merged"
> git push
Task:合作開發 1A2B 猜數字遊戲
三個人一組
透過 Git / GitHub 協作開發猜數字遊戲
A
B
C
A
B
C
A
B
C
新增協作者
Repo 主頁
> Settings
> Collaborators
> Add people
A
B
C
ssh-keygen
cat ~/.ssh/id_rsa.pub
把 repo clone 到本機上
github.com/username/repo-name
A
B
C
git@github.com:username/repo-name.git
cd /path/to/any/directory
git clone <repo_url>
cd repo-name
A 先打個基本設定
A
B
C
*.exe
.gitignore
#include<stdio.h>
#include<stdlib.h>
int main()
{
}
main.c
git add .
git commit -m "template"
git push origin main
5
main
BC 把 A 的修改 pull 下來
A
B
C
git pull
5
main
B 強迫症發作,改了 A 的 coding style
A
B
C
#include<stdio.h>
#include<stdlib.h>
int main(){
}
main.c
git add .
git commit -m "coding style!!"
git push origin main
5
main
7
main
C 寫了一些遊戲基本流程
A
B
C
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define len 4
void generate(char *s){
// TODO
}
void input(char *s){
// TODO
}
void response(char *s, char *a){
// TODO
}
int main()
{
char ans[10000], str[10000];
generate(ans);
while(true){
input(str);
response(str, ans);
}
printf("You won!\n");
}
main.c
git add .
git commit -m "game flow"
git push origin main
5
7
main
To github.com:username/repo-name.git
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'github.com:username/repo-name.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
void response(char *s, char *a){
// TODO
}
<<<<<<< HEAD
int main()
{
char ans[10000], str[10000];
generate(ans);
=======
int main(){
>>>>>>> <commit ID>
while(true){
input(str);
response(str, ans);
git pull
void response(char *s, char *a){
// TODO
}
int main(){
char ans[10000], str[10000];
generate(ans);
while(true){
input(str);
response(str, ans);
git add .
git commit -m "merge!"
git push origin main
C
5
7
origin/main
8
main
8
5
7
origin/main
8
main
5
7
main
5
7
8
8
main
pull
merge
push
5
8
main
分工:
A 維護 main
B 處理 input
C 處理 output
A
B
C
5
7
8
8
main
input
output
git pull
git checkout -b "input"
B
C
git pull
git checkout -b "output"
A 簡單加上了分隔線
A
B
C
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define len 4
void generate(char *s){
// TODO
}
void input(char *s){
// TODO
}
void response(char *s, char *a){
// TODO
}
int main(){
char ans[10000], str[10000];
generate(ans);
while(true){
printf("==========\n");
input(str);
response(str, ans);
}
printf("You won!\n");
}
main.c
git add .
git commit -m "add separator"
git push origin main
5
7
8
8
main
input
output
10
main
B 完成了數字生成和使用者輸入
A
B
C
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<string.h>
#define len 4
bool valid(char *s){
if(strlen(s) != len) return false;
for(int i = 0; i < len; i++){
for(int j = 0; j < len; j++){
if(i != j && s[i] == s[j]){
return false;
}
}
}
return true;
}
void generate(char *s){
printf("Set the answer (0 for auto generation): ");
scanf("%s", s);
if(s[0] == '0' && strlen(s) == 1){
srand(time(0));
while(true){
for(int i = 0; i < len; i++){
s[i] = '0' + rand() % 10;
}
s[len] = '\0';
if(valid(s)){
break;
}
}
}else{
if(!valid(s)){
printf("Invalid input\n");
generate(s);
}else{
printf("\033[1A\x1b[2K");
}
}
}
void input(char *s){
printf("Guess a 4-digit number: ");
scanf("%s", s);
}
void response(char *s, char *a){
// TODO
}
int main(){
char ans[10000], str[10000];
generate(ans);
while(true){
input(str);
if(!valid(str)){
printf("Invalid input\n");
}else{
response(str, ans);
}
}
printf("You won!\n");
}
main.c
git add .
git commit -m "finish input"
git push origin input
5
7
8
8
input
output
10
main
11
input
C 完成回覆函數和勝利判斷
A
B
C
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#define len 4
void generate(char *s){
// TODO
}
void input(char *s){
// TODO
}
bool win(char *s, char *a){
return strcmp(s, a) == 0;
}
void response(char *s, char *a){
int cnt_a = 0, cnt_b = 0;
for(int i = 0; i < len; i++){
if(s[i] == a[i]){
cnt_a++;
}else{
for(int j = 0; j < len; j++){
if(s[i] == a[j]){
cnt_b++;
break;
}
}
}
}
if(cnt_a) printf("%dA", cnt_a);
if(cnt_b) printf("%dB", cnt_b);
printf("\n");
}
int main(){
char ans[10000], str[10000];
generate(ans);
while(true){
input(str);
if(win(str, ans)){
break;
}else{
response(str, ans);
}
}
printf("You won!\n");
}
main.c
git add .
git commit -m "finish output"
git push origin output
5
7
8
8
10
main
11
input
12
output
output
身為 main branch 的維護者, A 要負責將 feature branches 合併進 main
A
B
C
git pull
git merge origin/input
5
7
8
8
10
main
11
input
12
output
13
main
身為 main branch 的維護者, A 要負責將 feature branches 合併進 main
A
B
C
git merge origin/output
5
7
8
8
10
11
input
12
output
13
main
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
<<<<<<< HEAD
#include<time.h>
=======
>>>>>>> output
#include<string.h>
#define len 4
bool valid(char *s){
if(strlen(s) != len) return false;
for(int i = 0; i < len; i++){
for(int j = 0; j < len; j++){
if(i != j && s[i] == s[j]){
return false;
}
}
}
return true;
}
void generate(char *s){
printf("Set the answer (0 for auto generation): ");
scanf("%s", s);
if(s[0] == '0' && strlen(s) == 1){
srand(time(0));
while(true){
for(int i = 0; i < len; i++){
s[i] = '0' + rand() % 10;
}
s[len] = '\0';
if(valid(s)){
break;
}
}
}else{
if(!valid(s)){
printf("Invalid input\n");
generate(s);
}else{
printf("\033[1A\x1b[2K");
}
}
}
void input(char *s){
printf("Guess a 4-digit number: ");
scanf("%s", s);
}
bool win(char *s, char *a){
return strcmp(s, a) == 0;
}
void response(char *s, char *a){
int cnt_a = 0, cnt_b = 0;
for(int i = 0; i < len; i++){
if(s[i] == a[i]){
cnt_a++;
}else{
for(int j = 0; j < len; j++){
if(s[i] == a[j]){
cnt_b++;
break;
}
}
}
}
if(cnt_a) printf("%dA", cnt_a);
if(cnt_b) printf("%dB", cnt_b);
printf("\n");
}
int main(){
char ans[10000], str[10000];
generate(ans);
while(true){
printf("==========\n");
input(str);
<<<<<<< HEAD
if(!valid(str)){
printf("Invalid input\n");
=======
if(win(str, ans)){
break;
>>>>>>> output
}else{
response(str, ans);
}
}
printf("You won!\n");
}
身為 main branch 的維護者, A 要負責將 feature branches 合併進 main
A
B
C
git add .
git commit -m "merge output"
5
7
8
8
10
11
input
12
output
13
main
14
main
5
7
8
8
10
11
input
12
output
13
14
main
git push origin main
gcc game.c -o game.exe
./game.exe
更系統化的分工合作
一個團隊的紀律
avoid conflicts!!
5
7
8
8
10
11
input
12
output
13
14
main
大家都想在 main branch 上做事
\(\Rightarrow\) 衝突多、merge 多、歷史記錄亂
每個人在自己的 branch 上做事
彼此不互相干擾
git rebase
A
B
C
A
B
C
A
B
C
B
C
A
B
C
git merge
git rebase
A
B
C
A
B
C
A
B
C
B
D
A
B
C
git merge
git rebase
git merge
git rebase
A
B
C
B
D
A
B
C
git init
git config [--global] user.name <bob>
git config [--global] user.email <bob@csie.ntu.edu.tw>
// function.h
#ifndef FUNCTION_H
#define FUNCTION_H
#include <stdio.h>
#include <math.h>
#include <string.h>
void clear_screen() {
printf("clear_screen\n");
}
void print_screen() {
printf("print_screen\n");
}
#endif
// donut.c
#include <unistd.h>
#include "function.h"
int main() {
clear_screen() ;
for(;;) {
print_screen() ;
}
}
# Makefile
run:
gcc donut.c -lm -Wall -Wextra
// function.h
#ifndef FUNCTION_H
#define FUNCTION_H
#include <stdio.h>
#include <math.h>
#include <string.h>
void clear_screen() {
printf("\x1b[2J");
}
void print_screen() {
printf("print_screen\n");
}
void hide_cursor() {
printf("\033[?25l") ;
}
void reset_cursor() {
printf("\x1b[H");
}
#endif
// donut.c
#include <unistd.h>
#include "function.h"
int main() {
clear_screen() ;
hide_cursor() ;
for(;;) {
reset_cursor() ;
print_screen() ;
usleep(30000) ;
}
}
git add <filename>
git status
git commit -m "<message>"
git restore [--staged] <filename>
git rm [--cache] <filename>
// function.h
#ifndef FUNCTION_H
#define FUNCTION_H
#include <stdio.h>
#include <math.h>
#include <string.h>
void clear_screen() {
printf("\x1b[2J");
}
void print_screen(float A, float B) {
printf("print_screen %f %f\n", A, B);
}
void hide_cursor() {
printf("\033[?25l") ;
}
void reset_cursor() {
printf("\x1b[H");
}
#endif
// donut.c
#include <unistd.h>
#include "donut.h"
#include "function.h"
int main() {
float A = 0 ;
float B = 0 ;
clear_screen() ;
hide_cursor() ;
for(;;) {
reset_cursor() ;
print_screen(A, B) ;
A += omega_A ;
B += omega_B ;
usleep(30000) ;
}
}
// donut.h
#ifndef DONUT_H
#define DONUT_H
const float omega_A = 0.07;
const float omega_B = 0.04;
#endif
git log
git reset [--soft|--hard] <commit>
git stash
git stash pop
git checkout <hash>
A
B
C
A
B
C
新增協作者
Repo 主頁
> Settings
> Collaborators
> Add people
A
B
C
ssh-keygen
cat ~/.ssh/id_rsa.pub
把 repo clone 到本機上
github.com/username/repo-name
A
B
C
git@github.com:username/repo-name.git
cd /path/to/any/directory
git clone <repo_url>
cd repo-name
git remote add origin git@github.com:Ccucumber12/myrepo.git
git branch -M main
git push -u origin main
git clone git@github.com:Ccucumber12/myrepo.git
// function.h
#ifndef FUNCTION_H
#define FUNCTION_H
#include <stdio.h>
#include <math.h>
#include <string.h>
void clear_screen() {
printf("\x1b[2J");
}
void print_screen(float A, float B) {
printf("print_screen %f %f\n", A, B);
}
void hide_cursor() {
printf("\033[?25l") ;
}
void reset_cursor() {
printf("\x1b[H");
}
coordinate get_projection(float theta, float phi, float A, float B) {
return (coordinate){ .x=0, .y=0, .z=0 };
}
float get_luminance(float theta, float phi, float A, float B) {
return 0;
}
void get_output(float L, coordinate pos) {
}
#endif
// donut.c
#include <unistd.h>
#include "donut.h"
#include "function.h"
int main() {
float A = 0 ;
float B = 0 ;
clear_screen() ;
hide_cursor() ;
for(;;) {
for (float theta=0; theta < 2*pi; theta += dtheta) {
for(float phi=0; phi < 2*pi; phi += dphi) {
coordinate pos = get_projection(theta, phi, A, B) ;
float L = get_luminance(theta, phi, A, B) ;
get_output(L, pos) ;
}
}
reset_cursor() ;
print_screen(A, B) ;
A += omega_A ;
B += omega_B ;
usleep(30000) ;
}
}
// donut.h
#ifndef DONUT_H
#define DONUT_H
const float pi = 3.1415926 ;
const float dtheta = 0.07 ;
const float dphi = 0.02 ;
const float omega_A = 0.07;
const float omega_B = 0.04;
typedef struct Tcoordinate {
int x ;
int y ;
float z ;
} coordinate ;
#endif
// function.h
#ifndef FUNCTION_H
#define FUNCTION_H
#include <stdio.h>
#include <math.h>
#include <string.h>
void clear_screen() {
printf("\x1b[2J");
}
void print_screen(float A, float B) {
printf("print_screen %f %f\n", A, B);
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++)
putchar(output[j][i]);
putchar('\n');
}
}
void hide_cursor() {
printf("\033[?25l") ;
}
void reset_cursor() {
printf("\x1b[H");
}
void reset_values() {
memset(output, (int)' ', sizeof(output)) ;
memset(bestOOZ, 0, sizeof(bestOOZ)) ;
}
coordinate get_projection(float theta, float phi, float A, float B) {
return (coordinate){ .x=0, .y=0, .z=0 };
}
float get_luminance(float theta, float phi, float A, float B) {
return 0;
}
void get_output(float L, coordinate pos) {
}
#endif
// donut.c
#include <unistd.h>
#include "donut.h"
#include "function.h"
int main() {
float A = 0 ;
float B = 0 ;
clear_screen() ;
hide_cursor() ;
for(;;) {
reset_values() ;
for (float theta=0; theta < 2*pi; theta += dtheta) {
for(float phi=0; phi < 2*pi; phi += dphi) {
coordinate pos = get_projection(theta, phi, A, B) ;
float L = get_luminance(theta, phi, A, B) ;
get_output(L, pos) ;
}
}
reset_cursor() ;
print_screen(A, B) ;
A += omega_A ;
B += omega_B ;
usleep(30000) ;
}
}
// donut.h
#ifndef DONUT_H
#define DONUT_H
#define width 30
#define height 30
const float pi = 3.1415926 ;
const float dtheta = 0.07 ;
const float dphi = 0.02 ;
const float omega_A = 0.07;
const float omega_B = 0.04;
typedef struct Tcoordinate {
int x ;
int y ;
float z ;
} coordinate ;
char output[height][width] ;
float bestOOZ[height][width] ;
#endif
git pull --ff-only
git push
// function.h
#ifndef FUNCTION_H
#define FUNCTION_H
#include <stdio.h>
#include <math.h>
#include <string.h>
void clear_screen() {
printf("\x1b[2J");
}
void print_screen(float A, float B) {
printf("print_screen %f %f\n", A, B);
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++)
putchar(output[j][i]);
putchar('\n');
}
}
void hide_cursor() {
printf("\033[?25l") ;
}
void reset_cursor() {
printf("\x1b[H");
}
void reset_values() {
memset(output, (int)' ', sizeof(output)) ;
memset(bestOOZ, 0, sizeof(bestOOZ)) ;
}
coordinate get_projection(float theta, float phi, float A, float B) {
float costheta = cos(theta), sintheta = sin(theta);
float cosphi = cos(phi), sinphi = sin(phi);
float cosA = cos(A), sinA = sin(A) ;
float cosB = cos(B), sinB = sin(B) ;
// the x,y coordinate of the circle before revolving
float circlex = R2 + R1*costheta;
float circley = R1*sintheta;
// final 3D (x,y,z) coordinate after rotations
coordinate pos ;
float x = circlex*(cosB*cosphi + sinA*sinB*sinphi) - circley*cosA*sinB ;
float y = circlex*(sinB*cosphi - sinA*cosB*sinphi) + circley*cosA*cosB ;
float z = donut_distance + cosA*circlex*sinphi + circley*sinA ;
// (x,y,z) after projection
pos.x = (int) (width/2 + render_distance*x/z);
pos.y = (int) (height/2 - render_distance*y/z);
pos.z = z ;
return pos ;
}
float get_luminance(float theta, float phi, float A, float B) {
// calculate luminance, range from -sqrt(2) to +sqrt(2).
return cos(phi)*cos(theta)*sin(B) - cos(A)*cos(theta)*sin(phi) - sin(A)*sin(theta) + cos(B)*(cos(A)*sin(theta) - cos(theta)*sin(A)*sin(phi));
}
void get_output(float L, coordinate pos) {
}
#endif
// donut.h
#ifndef DONUT_H
#define DONUT_H
#define width 30
#define height 30
const float pi = 3.1415926 ;
const float dtheta = 0.07 ;
const float dphi = 0.02 ;
const float omega_A = 0.07;
const float omega_B = 0.04;
const float R1 = 1 ;
const float R2 = 2 ;
const float donut_distance = 5 ;
const float render_distance = width*donut_distance*3/(8*(R1+R2));
typedef struct Tcoordinate {
int x ;
int y ;
float z ;
} coordinate ;
char output[height][width] ;
float bestOOZ[height][width] ;
#endif
// function.h
#ifndef FUNCTION_H
#define FUNCTION_H
#include <stdio.h>
#include <math.h>
#include <string.h>
void clear_screen() {
printf("\x1b[2J");
}
void print_screen(float A, float B) {
printf("print_screen %f %f\n", A, B);
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++)
putchar(output[j][i]);
putchar('\n');
}
}
void hide_cursor() {
printf("\033[?25l") ;
}
void reset_cursor() {
printf("\x1b[H");
}
void reset_values() {
memset(output, (int)' ', sizeof(output)) ;
memset(bestOOZ, 0, sizeof(bestOOZ)) ;
}
coordinate get_projection(float theta, float phi, float A, float B) {
return (coordinate){ .x=0, .y=0, .z=0 };
}
float get_luminance(float theta, float phi, float A, float B) {
return 0;
}
void get_output(float L, coordinate pos) {
// larger ooz means closer to viewer, reset output for closer z
float ooz = 1 / pos.z ; // one over z
if(ooz > bestOOZ[pos.y][pos.x]) {
bestOOZ[pos.y][pos.x] = ooz ;
output[pos.y][pos.x] = L > 5 ? '@' : '.';
}
}
#endif
git push # reject
git pull --ff-only
git merge origin/main
git push
// function.h
#ifndef FUNCTION_H
#define FUNCTION_H
#include <stdio.h>
#include <math.h>
#include <string.h>
void clear_screen() {
printf("\x1b[2J");
}
void print_screen(float A, float B) {
printf("print_screen %f %f\n", A, B);
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++)
putchar(output[j][i]);
putchar('\n');
}
}
void hide_cursor() {
printf("\033[?25l") ;
}
void reset_cursor() {
printf("\x1b[H");
}
void reset_values() {
memset(output, (int)' ', sizeof(output)) ;
memset(bestOOZ, 0, sizeof(bestOOZ)) ;
}
coordinate get_projection(float theta, float phi, float A, float B) {
float costheta = cos(theta), sintheta = sin(theta);
float cosphi = cos(phi), sinphi = sin(phi);
float cosA = cos(A), sinA = sin(A) ;
float cosB = cos(B), sinB = sin(B) ;
// the x,y coordinate of the circle before revolving
float circlex = R2 + R1*costheta;
float circley = R1*sintheta;
// final 3D (x,y,z) coordinate after rotations
coordinate pos ;
float x = circlex*(cosB*cosphi + sinA*sinB*sinphi) - circley*cosA*sinB ;
float y = circlex*(sinB*cosphi - sinA*cosB*sinphi) + circley*cosA*cosB ;
float z = donut_distance + cosA*circlex*sinphi + circley*sinA ;
// (x,y,z) after projection
pos.x = (int) (width/2 + render_distance*x/z);
pos.y = (int) (height/2 - render_distance*y/z);
pos.z = z ;
return pos ;
}
float get_luminance(float theta, float phi, float A, float B) {
// calculate luminance, range from -sqrt(2) to +sqrt(2).
return cos(phi)*cos(theta)*sin(B) - cos(A)*cos(theta)*sin(phi) - sin(A)*sin(theta) + cos(B)*(cos(A)*sin(theta) - cos(theta)*sin(A)*sin(phi));
}
void get_output(float L, coordinate pos) {
}
#endif
// donut.h
#ifndef DONUT_H
#define DONUT_H
#define width 30
#define height 30
const float pi = 3.1415926 ;
const float dtheta = 0.07 ;
const float dphi = 0.02 ;
const float omega_A = 0.07;
const float omega_B = 0.04;
const float R1 = 1 ;
const float R2 = 2 ;
const float donut_distance = 5 ;
const float render_distance = width*donut_distance*3/(8*(R1+R2));
typedef struct Tcoordinate {
int x ;
int y ;
float z ;
} coordinate ;
char output[height][width] ;
float bestOOZ[height][width] ;
#endif
// function.h
#ifndef FUNCTION_H
#define FUNCTION_H
#include <stdio.h>
#include <math.h>
#include <string.h>
void clear_screen() {
printf("\x1b[2J");
}
void print_screen(float A, float B) {
printf("print_screen %f %f\n", A, B);
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++)
putchar(output[j][i]);
putchar('\n');
}
}
void hide_cursor() {
printf("\033[?25l") ;
}
void reset_cursor() {
printf("\x1b[H");
}
void reset_values() {
memset(output, (int)' ', sizeof(output)) ;
memset(bestOOZ, 0, sizeof(bestOOZ)) ;
}
coordinate get_projection(float theta, float phi, float A, float B) {
return (coordinate){ .x=0, .y=0, .z=0 };
}
float get_luminance(float theta, float phi, float A, float B) {
return 0;
}
void get_output(float L, coordinate pos) {
// larger ooz means closer to viewer, reset output for closer z
float ooz = 1 / pos.z ; // one over z
if(ooz > bestOOZ[pos.y][pos.x]) {
bestOOZ[pos.y][pos.x] = ooz ;
output[pos.y][pos.x] = L > 5 ? '@' : '.';
}
}
#endif
# create local branch
git branch <bob>
git checkout <bob>
git push -u origin <bob>
# merge and push
git checkout main
git pull
git merge <bob>
# pull alice branch and checkout
git pull
git switch <alice>
git checkout -b <alice> origin/<alice>
git branch -d <bob> # delete local branch
git push origin -d <bob> # delete remote branch
git pull --prune # remove remote deleted branch
// function.h
#ifndef FUNCTION_H
#define FUNCTION_H
#include <stdio.h>
#include <math.h>
#include <string.h>
void clear_screen() {
printf("\x1b[2J");
}
void print_screen(float A, float B) {
printf("print_screen %f %f\n", A, B);
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++)
putchar(output[j][i]);
putchar('\n');
}
}
void hide_cursor() {
printf("\033[?25l") ;
}
void reset_cursor() {
printf("\x1b[H");
}
void reset_values() {
memset(output, (int)' ', sizeof(output)) ;
memset(bestOOZ, 0, sizeof(bestOOZ)) ;
}
coordinate get_projection(float theta, float phi, float A, float B) {
float costheta = cos(theta), sintheta = sin(theta);
float cosphi = cos(phi), sinphi = sin(phi);
float cosA = cos(A), sinA = sin(A) ;
float cosB = cos(B), sinB = sin(B) ;
// the x,y coordinate of the circle before revolving
float circlex = R2 + R1*costheta;
float circley = R1*sintheta;
// final 3D (x,y,z) coordinate after rotations
coordinate pos ;
float x = circlex*(cosB*cosphi + sinA*sinB*sinphi) - circley*cosA*sinB ;
float y = circlex*(sinB*cosphi - sinA*cosB*sinphi) + circley*cosA*cosB ;
float z = donut_distance + cosA*circlex*sinphi + circley*sinA ;
// (x,y,z) after projection
pos.x = (int) (width/2 + render_distance*x/z);
pos.y = (int) (height/2 - render_distance*y/z);
pos.z = z ;
return pos ;
}
float get_luminance(float theta, float phi, float A, float B) {
// calculate luminance, range from -sqrt(2) to +sqrt(2).
return cos(phi)*cos(theta)*sin(B) - cos(A)*cos(theta)*sin(phi) - sin(A)*sin(theta) + cos(B)*(cos(A)*sin(theta) - cos(theta)*sin(A)*sin(phi));
}
void get_output(float L, coordinate pos) {
if (pos.x < 0 || pos.x >= width || pos.y < 0 || pos.y >= height)
return ;
// larger ooz means closer to viewer, reset output for closer z
float ooz = 1 / pos.z ; // one over z
if(ooz > bestOOZ[pos.y][pos.x]) {
bestOOZ[pos.y][pos.x] = ooz ;
output[pos.y][pos.x] = L > 5 ? '@' : '.';
}
}
#endif
// function.h
#ifndef FUNCTION_H
#define FUNCTION_H
#include <stdio.h>
#include <math.h>
#include <string.h>
void clear_screen() {
printf("\x1b[2J");
}
void print_screen(float A, float B) {
printf("print_screen %f %f\n", A, B);
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++)
putchar(output[j][i]);
putchar('\n');
}
}
void hide_cursor() {
printf("\033[?25l") ;
}
void reset_cursor() {
printf("\x1b[H");
}
void reset_values() {
memset(output, (int)' ', sizeof(output)) ;
memset(bestOOZ, 0, sizeof(bestOOZ)) ;
}
coordinate get_projection(float theta, float phi, float A, float B) {
float costheta = cos(theta), sintheta = sin(theta);
float cosphi = cos(phi), sinphi = sin(phi);
float cosA = cos(A), sinA = sin(A) ;
float cosB = cos(B), sinB = sin(B) ;
// the x,y coordinate of the circle before revolving
float circlex = R2 + R1*costheta;
float circley = R1*sintheta;
// final 3D (x,y,z) coordinate after rotations
coordinate pos ;
float x = circlex*(cosB*cosphi + sinA*sinB*sinphi) - circley*cosA*sinB ;
float y = circlex*(sinB*cosphi - sinA*cosB*sinphi) + circley*cosA*cosB ;
float z = donut_distance + cosA*circlex*sinphi + circley*sinA ;
// (x,y,z) after projection
pos.x = (int) (width/2 + render_distance*x/z);
pos.y = (int) (height/2 - render_distance*y/z);
pos.z = z ;
return pos ;
}
float get_luminance(float theta, float phi, float A, float B) {
// calculate luminance, range from -sqrt(2) to +sqrt(2).
return cos(phi)*cos(theta)*sin(B) - cos(A)*cos(theta)*sin(phi) - sin(A)*sin(theta) + cos(B)*(cos(A)*sin(theta) - cos(theta)*sin(A)*sin(phi));
}
char get_pattern(float L) {
// L is in range of -sqrt(2) to +sqrt(2)
// luminance_index is now in the range 0..11 (8*sqrt(2) = 11.3)
int luminance_index = L * 8 ;
return pattern[luminance_index] ;
}
void get_output(float L, coordinate pos) {
// check if out of range
if (L < 0)
return ;
// larger ooz means closer to viewer, reset output for closer z
float ooz = 1 / pos.z ; // one over z
if(ooz > bestOOZ[pos.y][pos.x]) {
bestOOZ[pos.y][pos.x] = ooz ;
output[pos.y][pos.x] = get_pattern(L) ;
}
}
#endif
// donut.h
#ifndef DONUT_H
#define DONUT_H
#define width 30
#define height 30
const float pi = 3.1415926 ;
const float dtheta = 0.07 ;
const float dphi = 0.02 ;
const float omega_A = 0.07;
const float omega_B = 0.04;
const float R1 = 1 ;
const float R2 = 2 ;
const float donut_distance = 5 ;
const float render_distance = width*donut_distance*3/(8*(R1+R2));
const char pattern[] = ".,-~:;=!*#$@" ;
typedef struct Tcoordinate {
int x ;
int y ;
float z ;
} coordinate ;
char output[height][width] ;
float bestOOZ[height][width] ;
#endif
git merge <bob> conflict !
vim <file>
git add <file>
git commit -m "message"
git push