<Branch란?>

" 같은 폴더 다른 세상" 

- branch에서 뭘하든 master에는 적용이 되지 않음

- 분할된 작업을 진행할 수 있음! 

- 즉, Git을 쓰는 이유가 됨

 

1. Branch 생성

git checkout -b (branch 이름)
# git checkout -b fix-mnist

- 작업의 명칭으로 branch 생성해주는 것이 좋음

 

2. 폴더 생성 및 수정작업

hello.txt를 만들고 commit 해보면.. 

3. 브랜치를 master branch로 변경하고 확인해보면

- hello.txt는 없는 것을 확인할 수 있음

 

4. 브랜치 삭제 

- master 브랜치에서 진행

git branch -D fix-mnist

 

< Branch에서 소스파일 수정하고 확인하기 >

1. 브랜치 생성

2. 수정할 파일 확인 

3. 원하는 편집기(vim, emacs, nano, 등으로 파일 수정하기

- nano로 실습

nano mnist/main.py

- 수정

- mac에서 nano 편집기 사용법

(1) 저장하기 : control + o

(2) 나가기 : control + x

 

4. 소스 파일 수정한 내용 확인하기 

git diff

5. commit 할 준비

(1) git status 명령어를 통해 "not staged" 확인

(2) git add 명령어 실행 

git add mnist/main.py

(참고) add 취소

git reset

6. commit하기 

git commit -m "수정한 내용"

7. git show 명령어를 통해 commit이 잘 되었는지 확인 

8. git status 명령어를 통해 현재 소스파일 상태 확인하기

- "nothing to commit, working tree clean" 확인

    == 현재 변화분도 없고 commit할 것이 없음 

(참고) 서명과 함께 commit

git commit -sm "커밋 메시지"

- "-s"를 함께 넣어 명령 실행

- git show를 실행하면 아래와 같이 "Signed-off-by :~~"가 표시됨

 

- Why 사용?  license에 관련하여 인식하였음을 표시

- 실제로는 "Contributor License Agreements" 많이 사용 

   (https://opensource.google/documentation/reference/cla) (https://cla.developers.google.com/clas

 

(참고) commit 수정하기

- 가장 최신 commit만 수정 가능

- 변경분을 추가하지않고 메시지만 추가할 수 있고, 수정하는 순간 commit ID 도 변경됨

git commit --amend

 

(참고) commit 삭제하기

- 최상위 commit부터 지울 수 있음(중간 X) 

# 생성한 commit 정보 확인하기
$ git log --oneline -3

# 최상위 commit부터 첫번째(1) 내용 삭제하기
$ git reset --hard HEAD~1

< Pull-Requset 하는 과정>

1. git branch 명령어를 통해 branch 확인하기

2. Fork 저장소에 업로드에서 commit 제출(pull-request) 준비하기 (push 하기)

git push origin (branch명)

token 만들어서 username, password 에 토큰 붙여넣기

3. Fork저장소(Github)에서 commit 제출하기

- 해당 branch에서 "Open pull request" 누르기

--> 현재까지의 과정은 아래와 같다

출처 : OpenUp 강의 자료

 

'Computer Science > git&github' 카테고리의 다른 글

Git&Github 고급 (Rebase)  (0) 2022.02.23
Stash vs Checkout  (0) 2022.02.16
개발자가 오픈소스 읽는 방법  (0) 2022.02.16
기본 Git&Github 협업과정  (0) 2022.02.16
[git & github] 깃허브  (0) 2020.05.18

< 개발자 별 commit 순위 확인 >

git shortlog -sn | nl

- s 옵션 : 개발자별 commit 개수 요약

- n 옵션 : 개발자별 commit 개수 순위 정리 

 

nl 명령 : line number 명시 (순위 표시 용으로 사용) 

 

- 해당 부분은 gui 로 확인 가능 ( Github 해당 프로젝트 -> Insights -> Contributors) 

Q. 왜 GUI로 보지않고 CLI 로 보는가? 

A. 전체의 history보다 최근의 history,  특정 폴더에 집중적으로, 등등 확인하기 위해 

이렇게 세부적인 사항은 GUI로 확인할 수 없음 

즉, 세부적인 경향 파악을 위해 GUI가 아닌 CLI를 사용

 

(1) 특정 폴더에 집중적으로 순위 확인 

git shortlog -sn -- (디렉토리명)

(2) 특정 폴더 + 특정날짜 이후(최근) 순위 확인 

git shortlog -sn --after=2019-01-01 -- mnist

(3) merge commit 제거한 순위 확인

git shortlog -sn --no-merges

* commit : 소스 변경 히스토리 단위

* merge commit : "병합이 되었음을 나타내는 빈 commit" 

 

< 전체 소스파일 수정내역 개수 (commit 개수) 확인 >

git log --oneline | wc -l

wc -l 명령 : (파일) 라인 수 개수 측정

- GUI로도 확인 가능 -> "숫자"commits

- 팀 프로젝트의 commit 전체 개수 == base commit이라고 부름 

 

Q. base commit 은 계속 똑같은가? 

A. No. 당연히 변경됨. **우리는 base commit 위에 작업을 함**

 

(1) 전체 소스파일 수정내역 리스트 확인

git log --oneline

- 실행시 나오는 노란색글씨 : 소스파일 수정내역 고유한 ID (SHA1 해시값)

(2)전체 소스파일 수정내역(commit) 자세히 확인

git log -p

(3) 특정 날짜 기준 수정내역(commit) 확인 

git log --oneline --after=2020-01-01 --before=2020-06-30

(4) 특정 날짜 기준 수정내역(commit) 개수 확인

git log --oneline --after=2020-06-01 --before=2020-06-30 | wc

(5) 특정 날짜+파일/폴더 기준 수정내역(commit) 개수 확인

git log --oneline --after=2020-06-01 --before=2020-06-30 -- mnist/

- 협업 시 특정파일에 집중해서 개발하므로, 필요! 

(6) 최근이 아닌 옛날 것부터 소스파일 수정내역(commit) 확인

git log --oneline --reverse

* reverse 사용 시 주의 

- 첫번째꺼는 옛날꺼부터 3개

- 두번째 명령은 최신꺼 3개 중 거꾸로! 

 

< 특정 ID의 소스파일 수정 내역(commit) 내용 확인 >

git show (ID)

- commit 단위로 어떤 것을 수정했는지 확인할 수 있음

(1) 특정 ID의 소스파일 수정 파일 확인

git show 6c8e2ba | grep "diff --git"

(2) 특정 ID의 소스파일 수정 파일 개수 확인

git show 6c8e2ba | grep "diff --git" | wc -l

(3)전체 소스파일 수정내역(commit) 리스트에서, Merge commit 수정내역 확인

 

 

'Computer Science > git&github' 카테고리의 다른 글

Stash vs Checkout  (0) 2022.02.16
Branch 에서 소스파일 생성 및 수정  (0) 2022.02.16
기본 Git&Github 협업과정  (0) 2022.02.16
[git & github] 깃허브  (0) 2020.05.18
[git & github] 브랜치  (0) 2020.05.17

-Open UP에서 공개SW 실습교육 1일차-

<협업과정>

1. 참여할 프로젝트 Fork 복사

2. Fork한 프로젝트를 다운로드(Clone)

3. 프로젝트 분석(개발 경향 파악) : https://bskwak.tistory.com/243 참고 

4. config 설정 (저자(author) 정보) 

<5~7 branch 에서 작업 -> https://bskwak.tistory.com/244 참고>

5. commit 설정( 소스코드 수정분)

6. Fork한 프로젝트에 commit 업로드 ( == Push

7. 참여할 프로젝트에 commit 제출 ( == Pull-Request : PR

 

 

※ Commit 이란?

1. log message(수정한 이유) 

- ⭐️협업 시 중요⭐️

2. patch/ diff (코드 수정: 변화분) 

- ⭐️+(초록)/-(빨강) 코드를 볼 줄 알아야 함

 

※ Fork

- 공식 오픈소스 프로젝트의 내용들을 복사하는 것 (Github 안에서)

 

※ Clone

- history와 함께 소스코드를 다운받는 것 

- zip 다운과는 다름! (zip : commit history은 다운 X)

 

더보기

Q. 원본 프로젝트가 수정되면 fork한 프로젝트에 자동으로 반영이 되나?

A. No. 자동으로 반영이 되진 않음. 따로 해결을 해야함

 

< CLI(명령어 기반 인터페이스) vs GUI(그래픽 유저 인터페이스) >

※ CLI 

- 사진파일 1만개를 폴더 분류할 때 유리 (쉽게 말해, 드래그 하는 것보다 명령어를 사용하는 것이 편리) 

- 장점 : 세부기능 활용, 자동화(스크립트) 

※ GUI 

- 포토샵, 영상편집, 등에 유리

- 장점 : 쓰기 좋음 

- 단점 : 세부기능 활용, 자동화가 어려움

 

< 기본 명령어>

★ pwd

- print working directory

- 현재 디렉토리 출력

 

 ls

- 현재 디렉토리 내부내용(내부에 존재하는 파일들) 출력

 

 cd

- change directory

- 현재 폴더 경로 변경 

cd .. : 상위 디렉토리로 이동 

 

 mv

- 파일명/디렉토리명 변경 or 파일  경로 이동

 

 rm

- rm 파일명 :파일 삭제

- rm -r 디렉토리명 : 디렉토리 삭제

 

 touch

- 빈 파일 생성

 

 clear

- 터미널 화면 정리

 

"command not found" 에러는 오타!

 

** 협업 프로세스 ** 

1,2 과정

master 표시 : git으로 관리되는 폴더이다! 라는 의미 

 

"No such file or directory"  에러 

- 해당 파일/폴더가 없는 경우에 발생 

- 이미 그 폴더에 들어와 있는 경우에도 발생

1. pwd 를 통해 어느 폴더에 있는지 확인 -> 이미 그 폴더인지 확인가능

2. ls 를 통해 현재 폴더 안에 무엇이 있는지 확인 -> 이동할지, 등등 결정 

 

* config 설정

git config -l

- config 설치 확인

 

* upstream vs origin

upstream : 공식 오픈소스에 push

origin : fork한 프로젝트/본인 프로젝트에 push

 

nums = [-2,1,-3,4,-1,2,1,-5,4]

이 배열에서 가장 큰 합을 가진 부분 배열은 [4,-1,2,1], 최대합은 6이다

 

어떻게 구해야 할까?

 

# Brute Force

카데인 알고리즘이 생각나지 않는다면 Brute Force 접근법으로 풀어야한다!

Brute-Force란, 모든 경우의 수를 다 구해본 후에 max값을 찾는것

풀이를 간략하게라도 적어보자면,,

1. nums의 index 0부터 시작해서 nums[0]과 함께할수있는(?) 모든 부분합을 구한다.

2. nums[0]의 가능한 모든 부분합 중 가장 큰 값을 변수/리스트/..에 저장

3. 나머지 index 1부터 n-1까지 '1','2' 반복

4. 그러면 리스트던지, 변수던지, 각 인덱스에 해당하는 큰 값들이 모아짐

5. 그 중에서 가장 큰 값을 출력하면 됨

 

이 방식은 풀이만 봐도 정말 비효율적이다..

배열의 크기가 작으면 물론 금방 풀리겠지만, 커지면 커질수록 '1-2'번 반복횟수가 많아지므로, 시간 복잡도는 O(n^2)가 된다

 

따라서 나는 "카데인 알고리즘"으로 접근했다

#카데인 알고리즘

예시로 들어 설명하면

nums=[-2,-1,5,-3]

일단 가볍게 아래와 같은 아이디어?로 시작한다

 

 

1. (자기자신 vs 자기자신+이전값) 들 중 큰값들만 선정

따라서 -2일땐 -2, -1일땐 -1, 5일땐 5, -3일땐 2

 

2. 1번 중 가장 큰 값 -> 5

 

 

 

 

이때, 조금만 더 생각해보면

어짜피 같은 값을 더해주니까 굳이 모든 값을 비교해볼 필요가 없다..

 

따라서,

1.  max(자기자신 vs 자기자신+이전값 중 가장 큰 값)

따라서 -2일땐 -2, -1일땐 -1, 5일땐 5, -3일땐 2

 

2. 1번 중 가장 큰 값 -> 5

 

 

 

 

"이전 값"을 사용하는 것이 가장 큰 핵심 포인트다!

 

여기서 나는 1번에 배열을 생성하여 저장하지 않고,

max(자기자신 vs 자기자신+이전값 중 가장 큰 값) = localMax 값과 이전 max값을 비교하여 globalMax 변수에 큰 값을 저장해서 풀었다..

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        localMax = nums[0]
        globalMax = nums[0]
        for i in range(1,len(nums)):
            localMax = max(nums[i],localMax+nums[i])
            globalMax = max(localMax,globalMax)
        return globalMax

배열 순회를 한번만 하므로, 카데인 알고리즘의 시간복잡도는 O(n)이다.

 

1. JAVA 풀이

class Solution {
    public void wiggleSort(int[] nums) {
        Arrays.sort(nums);
        int[] answer = new int[nums.length];
        int len = nums.length;
        
        if (nums.length %2 != 0)
            len = nums.length+1;
        
        for(int i=0;i< len/2; i++){
            answer[i*2] = nums[len/2-i-1];
        }
        
        for(int i=0; i< nums.length/2; i++){
            answer[i*2+1] = nums[nums.length-i-1];
        }

        for(int i=0;i<nums.length; i++){
            nums[i] = answer[i];
        }
    }
}

 

Java는 새로운 배열을 만들어 풀면 어렵지 않게 풀 수 있었다

nums를 정렬한 다음 짝수, 홀수 index에 역순으로 대입해주면 된다!

 

2. python 풀이

class Solution:
    def wiggleSort(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
  
        nums.sort()
        half = len(nums)//2 if len(nums)%2==0 else len(nums)//2+1
        nums[::2],nums[1::2] = nums[:half][::-1],nums[half:][::-1]

pop()을 사용하면서 풀고 싶었지만,, 아무리 생각해도 비효율적인 것 같아서 이것저것 시도해보다가,, 결국 다른사람 풀이와 동일한 풀이가.. 독창적인 풀이를 하고 싶었지만.. 실패

 

# nums = [3,2,6,4,5,1,0] 라 가정할때

 

1. 오름차순 정렬

# nums = [0,1,2,3,4,5,6]

 

2. half는 "nums길이의 반 값"인데, 홀수일 경우는 1을 더하도록 설정한다.

** "/"가 아닌 "//"를 써야함 -> "/"의 경우 홀수 일 경우, 소수점이 생기므로 다음 코드를 실행할 때 문제 발생

# len(nums)의 값은 7이므로 half의 값은 4가 된다

 

3. 짝수자리에 0~(half-1) index까지의 값을 역순으로 차례로 대입(변경), 홀수 자리에 half~끝 index까지의 값을 역순으로 차례로 대입(변경)

** 따로 코드를 분리해서 작성하면, 짝수 먼저 실행, 홀수 이후 실행으로 되므로 원하는 결과값이 나오지 않는다! 

    따라서 "동시 실행"이 가능하도록 코드 작성

 

참고로, 짝수의 경우를 예로 들면,,

nums[::2]= nums[:half][::-1]

참고로 [::2]는 2칸씩 띄어 읽는다는 의미!  따라서, nums[::2] 는 [0,2,4,6] 

nums[:half] 는 처음부터 (half-1)index까지의 값을 뜻하고

[::-1]은 그 값을 역순 처리한다는 뜻이다

 

그림으로 해당 풀이를 보면,,

 

+ Recent posts