Friday, September 20, 2019

Git 實用操作筆記

 
Forcibly cleaning everything including the directory, to make it clean again:
強行清除所有未 commit 的內容:
git clean -fd
git clean -nd (n is for preview, you can also use i for interactive)

Update everything from server
由 Server 取得更新:
git pull (--all)

Force manually update things from server
以 server 內容取代本機的內容:
git fetch
git reset --hard HEAD

----
放一個檔案去 Staged Area
# stage a file to staged area (a.k.a. add)
git add <filename>
git add -p <filename> #support --patch

反向操作
# unstage a file from staged area
git reset <filename>
git reset -p <filename> #support --patch

----

Reverting all changes to the latest commit, a.k.a. HEAD (discard changes) (for specific file, git checkout file is fine)
強行返回上一個 commit
git reset --hard HEAD

Move HEAD to previous commit
將 HEAD 指回上一個 commit
git reset --hard HEAD~1     #delete everything not committed.
git reset --soft HEAD~1     #keep unstaged things unchanged, combine HEAD~1 things and staged things to staged area
git reset --mixed HEAD~1    #(default) put all (HEAD~1 things, staged things and unstaged things) to unstaged area

Move HEAD to specific commit 
將 HEAD 移到某一個 commit
git reset --hard 0d1d7fc32

#regret about the reset changes
git reflog                    # to list all history
git reset --hard HEAD@{5}     # to reset back to original HEAD (use HEAD 5 as example)

# reverting single file to latest commit
git checkout -- filename

----

Save temporary changes without commit, then display clean workspace.  (a.k.a. "store/hide something secretly somewhere")
暫存未 commit 的內容到 stash 中
git stash
git stash -p #support --patch

Stash only staged files
git add app/controllers/cart_controller.php
git stash --keep-index
git reset

Restore (without popping out)
git stash apply (--index <?>)

Pop out
git stash pop

-----

Check out a remote branch as a local branch
開一個 local 分支,內容是 remote 分支:
git checkout -b LocalName origin/remotebranchname

----

# rewrite history (change previous commits)
git rebase -i HEAD~3     # use last 3 commits as an example

# rewrite history (amend last commit)
git commit --amend

# go back to previous commit (with a new commit)
git revert --no-commit 0766c053..HEAD
git commit

# move HEAD to previous commit then push to server
# (note: it rewrites history, generally not good, git revert might be better)
git reset --hard 0d1d7fc32
git push --force

----

# rename local branch / remote branch
git branch -m <old_name> OR
git branch -m <old_name> <new_name> OR
git push origin :<old-name> <new-name> (delete remote old-name branch and push local new-name branch)

# remove / delete local branch
git branch -d <branch name>

# remove / delete remote branch
git push <remote_name> --delete <branch_name>
git push <remote_name> :<branch_name>

#force update the remote branch list
git remote update origin --prune OR
git pull -p

# force push the local branch to remote (ignoring the remote status)
git push origin --force

----

# show abbreviated commit hash (short hash)
git log -1 --abbrev-commit

# remove all branches named with chriz.chow
git branch -r --list "*chriz.chow*" | sed 's/origin\///' | xargs git push origin --delete

----

Sometimes if you want to checkout a branch (e.g. dpp), but you also have a file called dpp.
When you run "git checkout dpp", Git does not know what operation you want.

To switch to dpp branch, you can run:
git switch dpp

To restore the dpp file, you can run:
git restore dpp

Alternatively, you can also add double-dash to indicate it is a file path:
git checkout dpp --

Tuesday, September 3, 2019

常用 Makefile 內建函式

 $(patsubst $(SRC)/%.c, $(BIN)/%, $(wildcard $(SRC)/*.c))
Name:     Text FunctionPattern Substitution
Rule:       output := $(patsubst pattern, replaced_with, input_text) 
Result:    From src/a.c src/b.c src/c.c to bin/a bin/b bin/c  .

$(subst ee,EE,feet on the street)
Name:     Text FunctionSubstitution
Rule:       output := $(subst from, to, text)
Result:    fEEt on the strEEt 

$(foreach OP, ProgA ProgB ProgC, good/$(OP))
Name:     Foreach Function
Rule:       output := $(foreach variable, list, text)
Result:    good/ProgA good/ProgB good/ProgC

$(filter-out main1.o main2.o, main1.o foo.o main2.o bar.o)
Name:     Text Function Filtering Out
Rule:       output := $(filter-out pattern, text)
Result:    foo.o bar.o

$(shell ls | wc -l )
Name:     Shell Function
Rule:       output := $(shell command)
Result:    Number of files

$(addprefix $(OBJDIR)/, foo.o bar.o baz.o)
Name:     File Name Function - Add Prefix
Rule:       output := $(addprefix prefix, names...)
Result:    objdir/foo.o objdir/bar.o objdir/baz.o 

$(findstring a, a b c)
Name:     Text Function - Find String
Rule:       output := $(findstring find, in). If it is found, output = find, else, output = empty
Result:     a

$(strip    a b c  )
Name:     Text Function - Strip (Remove leading and trailing whitespaces)
Rule:       output := $(strip string)
Result:    "a b c"

$(notdir src/foo.c bar.c)
Name:     File Name Function - Not Directory (basename)
Rule:       output := $(notdir names...)
Result:    foo.c bar.c

$(call reverse, a b)      #given that reverse = $(2) $(1)
Name:          Call Function
Behavior:     Call defined variable with parameters
Rule:            output := $(call variable, param, param...)
Result:         b a

$(eval $(call LINK_TARGET, $(BIN)/$(_bin)))     #given that LINK_TARGET is a variable defined earlier
Name:           Eval Function
Behavior:      Create a new makefile environment with the argument passed into eval, then parse it just like makefile syntax. 
Rule:             output(empty string) := $(eval argument)

Monday, September 2, 2019

Makefile 四種等號用法


Lazy Set

VARIABLE = value
Normal setting of a variable - values within it are recursively expanded when the variable is used, not when it's declared
(that means it fetches/parses the value only when you use the variable)

Immediate Set

VARIABLE := value
Setting of a variable with simple expansion of the values inside - values within it are expanded at declaration time.
(that means it fetches the value immediately, and store the content to the variable)

Set If Absent

VARIABLE ?= value
Setting of a variable only if it doesn't have a value

Append

VARIABLE += value
Appending the supplied value to the existing value (or setting to that value if the variable didn't exist)