2020년 4월 30일 목요일
2019년 7월 13일 토요일
#45 알고리즘 연습 JadenCase 문자열 만들기 python
JadenCase 문자열 만들기
문제 설명
제한 조건
- s는 길이 1 이상인 문자열입니다.
- s는 알파벳과 공백문자(" ")로 이루어져 있습니다.
- 첫 문자가 영문이 아닐때에는 이어지는 영문은 소문자로 씁니다. ( 첫번째 입출력 예 참고 )
입출력 예
| s | return |
|---|---|
3people unFollowed me | 3people Unfollowed Me |
for the last week | For The Last Week |
문제풀이 IDEA
글자의 첫번째만 대문자로 작성해줘야하므로1. 첫글자가 알파뱃인지 판단한다
2. 새로운 단어가 시작되는지 판단해준다.
이렇게 나눌 수 있겠다
따라서
1번의 경우에는 해당문자가 알파뱃범위에 있는지 판별해주고
2번의 경우 공백의 경우 조건문이 동작하지 않도록 장치를 설정해준다.
나의 코드
다른풀이의 주요 개념
str.title() 단어들의 첫글자를 대문자로 변경해주지만 공백 2개 or 숫자 시작같은경우 올바르지 못한 출력을 보인다.
그리고 split을 이용해 나눈 case가 많이 보이는데 split을 써서 나누게 되면 공백을 기준으로 나뉘게 되므로
공백이 2개 이상 있는 경우 처리가 힘들어진다.
따라서 간편한 방법이지만 공백이 1개인 문자열에서 밖에 못쓰다는 단점이 있다.
2019년 7월 12일 금요일
# 5 자료구조&알고리즘 Stack
Linear Structure
제거(remove)와 추가(add) 과정에서 끝(end)를 선택하는 방식에 따라 데이터 구조가 달라진다.
이러한 구조들은 많은 알고리즘과 함께 다양한 문제를 해결하는데 쓰인다
Stack ( or push-down stack )
아이템의 추가와 제거가 Top에서 이루어지는것 ( Top 의 반대는 Base라 한다)
따라서 LIFO ( last - in first-out ), 후입선출이라고 하기도 하는데
최신의 아이템이 Top, 오래된 아이템이 Base에 가까운 구조이다
이러한 구조는 책이 쌓여 있는 모양과도 같으며 다른 책을 확인하기 위해서는 Top position의 책을 제거해야한다
따라서 책을 쌓기 시작한 순서와 책이 제거되는 순서는 반대인데 이러한 아이디어가 Stack의 핵심이다.
(예를 들어보면 1번책 2번책 3번책 순으로 쌓았으면 제거는 3번책 2번책 1번책)
==> 삽입순서와 제거순서가 서로 역순의 관계이다.
e.g) 컴퓨터에서 이러한 특징은 web page의 back 버튼으로 알수있는데
page이동이 stack으로 저장되어 지금 보고 있는 page가 Top,
처음 본 페이지가 Base에 위치하게 된다.
Stack Operations
- Stack() : 빈 스택을 생성 parameter : X return X
- push(item) : 새로운 item을 top으로 넣는다. parameter : item return X
- pop() : top으로 부터 item을 제거한다. parameter : X return : item
- peek() : top의 item을 확인, 제거아님 parameter : X return : item
- isEmpty() : stack이 비어있는지 확인한다. parameter : X return : boolean
- size() : stack의 item갯수를 return parameter : X return : integer
Stack 의 구현
우리는 강력하고 단순한 python의 collections, list를 이용해서 구현해보도록 하자
논리적인 특성을 유지하면서 다른 방법으로 stack을 구현할수 있는데
똑같이 작동한다 해도 성능에서 차이가 날 수 있으므로 효율적인 구현을 하는게 좋다.
e.g )
1. list의 end부분을 top으로 사용하는 경우 ==> pop() 과 append()가 모두 O(1)의 복잡도
2. list의 first 부분을 top으로 사용하는 경우== > pop(0) 과 insert(0)은 O(n)의 복잡도
따라서 같은 논리적 작업을 한다해도 1번의 구현이 훨씬 더 효율적이게 된다.
2019년 7월 7일 일요일
#데이터분석 Pandas Reperence
Pandas
- Pandas란 오픈소스로 높은 성능과 사용하기 쉬운 데이터 구조를 제공해준다
- Python language로 이루어진 데이터 분석 tool이다.
Pandas 시작
import pandas as pd #pandas 를 import하고 pd라고 줄여서 사용
Pandas 사용하기
데이터 입출력
data.to_csv('name.csv')data를 csv파일로 작성my_data = pandas.read_csv('name.csv)csv 파일을 읽어옴- 위의 csv는 각각 excel,hdf 로 바뀌어 사용 할수 있다
Series(Pandas의 자료구조)
특징
- index를 지정해 줄 수 있다.
- 지정하지 않을시 default값인 1,2,3,4가 지정된다
- mutable하다(index, value의 변경이 가능하다)
생성
- Series의 생성은 list자료형과 함께 index를 list의 형태로 넘겨주거나
- dictionary type을 Series로 변경해주면 key값이 index로 value가 value로 간다.
my_series = pd.Series([1,2,'good',True], index = ['하나','둘','셋','넷'])
print(my_series)
print("*"*30)
my_series2 = pd.Series({'첫째': 1, '둘째': 2, '셋째': 3})
print(my_series2)
하나 1
둘 2
셋 good
넷 True
dtype: object
******************************
첫째 1
둘째 2
셋째 3
dtype: int64
Series의 property
series.valuesSeries의 valueseries.indexSeries의 index (start는 포함, stop 이전)series.index.nameindex들의 name을 붙여줄 수 있다.
print(my_series.index) # iterable한 index object를 가져온다
print("")
print(my_series.values)
print("")
my_series.index.name ="index_col"
print(my_series)
Index(['하나', '둘', '셋', '넷'], dtype='object', name='index_col')
[1 2 'good' True]
index_col
하나 1
둘 2
셋 good
넷 True
dtype: object
Data Frame(Pandas의 자료구조)
특징
- 행의 index는 index로 열의 index는 columns으로
- mutable( 값의 변경이 가능하다)
생성- python의 dictionary, numpy 의 array로 생성가능
- dictionary로 생성시 key값이 열의 이름으로 들어간다
- 초기에 columns과 index(row)를 설정하여 생성할 수 있다.
- DataFrame(data, 설정, 설정)의 모양,
- 없는 index(columns)일때 NaN(Not a Number)으로 value를 채운다.
- 이미 있는 index일경우 순서를 설정에 맞춰준다
mydata = {'name' : ['jang','kim','lee','park'],'age':[25,23,27,21]}
mydf = pd.DataFrame(mydata)
mydf2 = pd.DataFrame(mydata,index=['하나','둘','셋','넷'],columns=['age','name','bool'])
print(mydf)
print("*"*20)
print(mydf2)
name age
0 jang 25
1 kim 23
2 lee 27
3 park 21
********************
age name bool
하나 25 jang NaN
둘 23 kim NaN
셋 27 lee NaN
넷 21 park NaN
Data Frame method & property
dataframe.valuesData Frame의 value들dataframe.index행의 index들dataframe.index.name행의 이름을 설정해줄 수 있다.dataframe.columns열의 index들dataframe.columns.name열의 이름을 설정해줄 수 있다.dataframe.describe()각각의 col에 해당하는 계산가능한 value로 count,평균,최소,최대 등을 표시(NaN은 계산불가)
mydf.index.name = '번호'
mydf.columns.name = "분류"
print(mydf)
mydf.describe() #name은 연산할수 있는 value가 없으므로 표시 X
분류 name age
번호
0 jang 25
1 kim 23
2 lee 27
3 park 21
| 분류 | age |
|---|---|
| count | 4.000000 |
| mean | 24.000000 |
| std | 2.581989 |
| min | 21.000000 |
| 25% | 22.500000 |
| 50% | 24.000000 |
| 75% | 25.500000 |
| max | 27.000000 |
DataFrame 조작 Reperence
Columns 편
dataframe['colname']dataframe의 coldataframe[['col','col2'...]]복수개의 coldataframe['colname'] = value
colname 존재 : index의 갯수만큼입력하면 index마다 다른 value대입(1개면 해당 value로 통일된 col생성)
colname 부재 : 새로운 열이 추가됨
value값에 Series가 오면 DataFrame의 index에 Series의 index를 맞춰 배열한다
del dataframe['col]col의 삭제dataframe['col']간의 사칙연산, 논리연산자(>,==,&,|) 사용가능하다Row 편
dataframe['start_index' : 'end_index']list의 indexing과 비슷한 모습dataframe.loc['rowname',<'target col name'>]
- Series의 모양으로 반환하는데 이때 Series의 index가 사실상은 columns들의 name이 되는것이다,
- rowname부분에 slice가 들어갈수 있다
- target부분을 안적어주면 default로 전체를 반환한다
- target부분에 list모양이면 특정 col만, slice면 해당 범위 col을 가져온다
dataframe.loc['rowname',<'target_col'>]= value새로운 행 삽입
- loc위치에 at을 사용할수 있고 더 빠르다
dataframe.iloc[]loc과 다르게 name이 아닌 index번호를 사용하여 가져옴
- iloc위치에 iat을 사용할수 있고 더 빠르다
dataframe.head(n)위에서 n개 만큼의 행을 읽어옴, n을 안줄시 default==5dataframe.tail()공통 편
dataframe.drop(name or condition , axis = 0 or 1)해당하는 행or열 삭제
- axis가 0이면 row(행)(default)
- axis가 1이면 col을 drop한다
dataframe.sum(axis=0 or 1)axis에 해당하는 계산가능한 value의 합
- sum이외에도 min,max,count,argmin(max),mean 등의 함수도 적용된다
위의 axis에서 알수있듯 ↓방향이 axis 0에 해당
➝ 방향이 axis 1에 해당한다
따라서 drop의 경우 ↓로 진행하다 조건에 맞는 row를 발견하면 삭제하고
sum은 ↓의 방향으로 더해나가는 것이다
dataframe.reindex(index = ... , col = ...)row와 col의 index를 다시 배열
dataframe.sort_index(axis=0 or 1, <ascending=bool> )index를 sort한다
- ascending option을 주지않으면 기본적으로 ascend = True 오름차순으로 된다
dataframe.sort_values(by=col,<ascending=bool>)col의 value들을 정렬한다
dataframe['row or col'].unique()행 or 열의 유니크한 값
dataframe['row or col'].value_counts()행 or 열의 value갯수 conunt
dataframe['row or col'].isin(value)행 or 열에서 value가 있는지 bool로 return
dataframe.Tdataframe을 전치한다
(행과 열을 바꾼다,(0.0),(1.1),(2.2)…를 이은 선분을 기준으로 좌우대칭으로 교환)
dataframe2 = dataframe.copy()dataframe을 복사한다NaN 편
삭제
dataframe.dropna(how='any')하나이상이 NaN인경우dataframe.dropna(how='all')모두 NaN변경
dataframe.fillna(value = somevalue)somevalue값으로 NaN값을 변경확인
dataframe.isnull()dataframe전체의 value에 대해 NaN인지 확인하여 bool로 리턴
Pandas의 functions
pandas.date_range('date(yyyymmdd',period=n)yyyymmdd부터 n일간의 range를 만들어준다- ```pandas.to_datetime(‘yyyymmdd’)```` yyyymmdd에 해당하는 Timestamp를 생성
Pandas 응용
Apply
dataframe.apply(function)data에 함수를 적용한다
- 이때 함수는 lambda function형태로 작성가능하다(lambda x: x.max()+x.min())
연결
pandas.concat([dataframe[0:1],dataframe[2:3]]dataframe의 2행을 제거하고 concat으로 연결pandas.merge(dataframe1, dataframe2, on = 'criteria')dataframe1과 2를 on에서 설정한 기준에 따라 merge한다Grouping
dataframe.groupby('value')특정 value를 기준으로 data를 그룹화한다(행합침)
- value부분에 list가 들어가 여러 기준이 적용될 수 있는데 앞에서부터 기준을 적용하여 grouping
2019년 7월 3일 수요일
#5 자료구조&알고리즘 - 알고리즘 분석(Big-O Notation)
알고리즘의 분석
✔ 알고리즘을 작성하는데는 어떠한 naming을 하냐도 중요한 요소로 작용한다
알고리즘 분석에 있어 고려해야할 것
1. 문제를 푸는데 요구되는 메모리 공간
2. 실행시간
그런데 이러한것을 측정할때 컴퓨터의 성능 및 프로그램, 언어에 의해서 속도가 달라질수 있다
따라서 우리는 공통된 측정방법이 필요하고 그게 바로
Big-O Notation이다.
Big-O Notation
할당문의 갯수를 계산해주면 되는데
이때 data의 규모가 커질수록 step의 수가 증가하고 함수 또한 빠르게 증가하므로
정확한 값보다는 비교를 위한 근사값을 사용한다.
e.g) n^2+1 , n^2 은 n의 갯수가 증가할수록 뒤에 붙은 1의 영향은 미미해진다
또한 n^2과 2n^2도 n의 갯수가 증가함에 따라 계수는 무시할 수 있을 영향력을 가진다.
따라서 7n^2 + 10n + 5의 경우 O(n^2)만 유의미한 값으로 근사치를 잡아준다
그런데 이렇게 계산을 함에 있어서 data set의 종류에 따라 best case 가 나타날수도 있고
worst case 가 나타날수도 있는데 우리는 일반적으로 average case를 생각하도록 한다
(n logn 과 n^2 중 누가 더 연산속도가 느린지 확인 할때는 임의로 특정 수를 넣어서
비교를 해주면 된다 예를 들어 n이 10일때 n logn은 10이 되고 n^2는 100이다.
따라서 n^2가 더 느린 것이다.)
Big-O를 이용한 알고리즘 분석 예시
Anagram 이라는 게임을 예로 들어보자.
(Anagram은 대기 - 기대 이와 같이 순서를 바꾸어 단어를 만드는 게임)
1. Checking Off : O(n^2)
A 단어와 B단어(list로 바꿔준다)에 대해서 A 단어의 0번째 index부터
B단어의 index들과 차근차근 비교하며 같은 character 를 발견하면 B의 해당 index의
문자를 None 으로 바꾼다. 만약 찾지 못하면 특정 flag를 false로 변경해주고 return한다
A의 한 index당 B의 index전체를 비교하므로 n*n n^2만큼 비교가 들어가게 된다.
2. Sort and Compare : O(n^2) or O(n logn)
A단어와 B단어를 list화 해준다음 sort를 이용해 정렬을 해주고 두 list의 index를 차례차례 학인해주며
같은 index에 다른 글자가 오면 다른 글자 조합인게 되므로 False를 반환해준다.
얼핏 보면 sort후 반복문을 통해 index비교를 해주기 때문에 O(n)만 볼수 있는데
sort자체가 O(n^2) or O(n logn)를 가지기에 여기에 집중해야한다
3. Brute Force : O(n!)
A단어를 구성하고 있는 문자열로 생성할수 있는 모든 단어를 생성한 뒤에 B가 그 안에 있는지 확인해주는 방법
A단어의 글자수가 n이면 첫째자리에 올수 있는 경우의수 n, 둘째 자리 n-1.... 처럼 이루어 지기때문에 n! 이 오게되고
n! 이라는 복잡도는 10!만 해도 어마어마해지기때문에 심지어 2^n 보다 안 좋은 효율이다.
4. Count and compare : O(n)
A단어와 B단어의 문자수를 저장할 수 있는 list를 생성하여 해당 문자가 발견될때 마다
list의 count를 늘려간다.
이 때 A와 B 다른 list를 구성하게 되므로 반복문은 중첩이 아니라 따로 구성이 되고
A, B의 문자수 list의 생성이 끝나면 반복문을 통해 index를 비교해가며 다르면
Anagram의 결과가 틀렸다고 해주면 된다.
단 위의 4번과 같은 경우에는 연산속도를 좋지만
메모리 공간을 사용함에 있어서는 추가 list를 만드는 행위 등으로 더 많은 소요가 있다.
따라서 이를 잘 절충하여 코드를 짤 필요가 있겠다.
위의 결과처럼 code의 구성 자체에서 성능의 차이를 불러 올수 있지만 python의 자료구조가 가지고 있는 operator의 차이로 인해 연산속도의 차이가 나는 경우도 있다.
특히 구성되는 과정에서 일반적으로 많이 사용하는 operation의 효율성을 위해 덜 사용되는 operation의 효율이 희생되기도 했다.
따라서 적절한 tool을 사용하는 것은 중요하다
python의 주요 데이터 구조의 시간복잡도
1. List
e.g ) 양의정수 list를 만드는 4가지 방법
1. concat (아주 느림)
list1 = []
for i in range(100):
list1 = list1 +[i]
2. append (일반적인 for문으로 만드는 방법)
list2 = []
for i in range(!00):
list2.append(i)
3. list comprehension (append에 비해 2배가량 빠름)
list3 = [ i for i in range(100)]
4. list range (가장 빠름)
list4 = list(range(100))
이처럼 똑같이 list를 만드는데 있어서도 연산속도의 차이가 많이 나기때문에 적절한 tool을 이용하는게 중요하다.
2. Dictionary
Dictionary도 List와 마찬가지로 index 와 set에 있어서 O(1)만큼의 효율을 보이나
하지만 중요한 것은 contain 여부를 확인하는 것도 Dictionary에서는 O(1)이라는 것이다.
시간 복잡도와 관련하여 추가 사항은 Time Complexity Wiki 를 참고하도록 하자.
#44 알고리즘연습 위장 python
위장
문제 설명
| 종류 | 이름 |
|---|---|
| 얼굴 | 동그란 안경, 검정 선글라스 |
| 상의 | 파란색 티셔츠 |
| 하의 | 청바지 |
| 겉옷 | 긴 코트 |
제한사항
- clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.
- 스파이가 가진 의상의 수는 1개 이상 30개 이하입니다.
- 같은 이름을 가진 의상은 존재하지 않습니다.
- clothes의 모든 원소는 문자열로 이루어져 있습니다.
- 모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 '_' 로만 이루어져 있습니다.
- 스파이는 하루에 최소 한 개의 의상은 입습니다.
입출력 예
| clothes | return |
|---|---|
[[yellow_hat, headgear], [ blue_sunglasses, eyewear], [ green_turban, headgear]] | 5 |
[[crow_mask, face], [ blue_sunglasses, face], [ smoky_makeup, face]] | 3 |
입출력 예 설명
headgear에 해당하는 의상이 yellowhat, greenturban이고 eyewear에 해당하는 의상이 blue_sunglasses이므로 아래와 같이 5개의 조합이 가능합니다.
1. yellow_hat
2. blue_sunglasses
3. green_turban
4. yellow_hat + blue_sunglasses
5. green_turban + blue_sunglasses
face에 해당하는 의상이 crowmask, bluesunglasses, smoky_makeup이므로 아래와 같이 3개의 조합이 가능합니다.
1. crow_mask
2. blue_sunglasses
3. smoky_makeup
문제풀이 IDEA
입력되는 form 이 [의상이름 , 의상종류] 이므로 이를 분리해서 dictionary로 저장한다
그런데 이떄 의상의 종류를 key값으로 이름을 value값으로 하여 종류에 따라 구분지어 볼수 있게 한다
그리고 의상종류가 이미 들어와 있으면 해당 key에 대한 value를 갱신해줘야하는데 이때 의상의 이름들을 저장해놓기 위해서 list를 value로 사용했다
마지막으로 최소 1개 이상의 종류를 입으므로 찾아보면
모자 2개 - 바지3개 일때
모자의 경우의수 0 1 2 (안 쓸때, 1번모자, 2번모자)
바지의 경우의 수 0 1 2 3 (안 입을때??, 1번바지, 2번바지, 3번바지)
모자의 경우의수 x 바지의 경우의 수 = > 12개 인데 이때는 모자와 바지를 둘다 안입는 경우도 포함
따라서 -1을 추가적으로 해줘야한다
나의 코드
다른코드
reduce는 python 3이상의 version부터 내장함수에서 제외되어 빠졌다
collections 의 counter 함수는 iterable한 애들을 받아 몇개씩 있는지 세어
key(종류)와 value(갯수)를 가진 dictionary로 생성해준다
2019년 6월 26일 수요일
#3 Git 분산버전관리시스템 - Basic - git의 명령어(심화)
원격 저장소와의 작업
pull
1 . local의 변경사항이 없으면 그냥 fast-forward 되고
2 . local의 변경사항이 있고 원격저장소의 변경사항도 있으며 둘의 충돌이 없으면
그냥 병합커밋이 만들어지고
3 . 충돌이 있으면 수동으로 해결한다음 commit해줘야한다
fetch
fetch를 실행하면 FETCH_HEAD라는 이름의 branch로 가져오기때문에
git branch checkout FETCH_HEAD 로 확인해볼 수 있다.
즉 fetch + merge 는 pull이다
push
(즉 로컬이 원격보다 commit이 앞서야한다)
임의로 원격저장소의 커밋을 바꾸면 그 원격 저장소와 동기화 된 다른 저장소의 커밋에도 영향을 주니 주의하자
Tag
커밋을 참조하기 쉽도록 이름을 붙이는것
🔖일반 태그 ( Lightweight tag )
이름만 붙일 수 있다
🔖주석 태그 ( Annotated tag )
이름을 붙일 수 있다
태그에 대한 설명 포함 가능
서명도 넣을 수 있다
이 태그를 만든 사람의 이름, 이메일과 태그를 만든 날짜 정보 포함 가능
일반적으로 release branch에서는 주석태그를 사용하여 상세한 정보를 포함하고
topic branch에서는 일반태그로 이름만 표시
태그 이름을 지정하여 checkout 하거나 reset할때 간단히 과거의 상태로 되돌릴수 있다.
-사용방법-
commit 후 최신 commit에 대해 사용해준다
🔖일반 태그
$ git tag <tag name>
commit 에 tagname을 붙여준다 (여러번 달아줄 수 있다)
$ git tag tag 목록을 볼 수 있다.
$ git log --decorate tag 정보까지 포함한 이력을 확인 할 수 있다. (그런데 git log만으로도 보인다)
🔖주석태그
$ git tag -a <tag name>
tag name으로 만들어진 tag에 내용을 추가할 수 있다
$ git tag -am "git tag 내용" <tag name> 한번에 처리 가능하다
태그 삭제
$ git tag -d <tag name>
Commit
--amend 옵션을 지정하여 commit을 하면 같은 브랜치 상에 이전 커밋내용을 수정할수 있다
$ git commit --amend
commit 에 amend옵션을 주게되면 최근 commit 내용이 뜨는데
commit massage를 수정해 줄 수 있다.
이때 add를 하고 commit --amend를 해주게 되면 index에 올라간 내용과 이전의 commit을 합쳐 새로운 commit을 만들어주는 것이 되자만
index에 올라간 변경사항 없이 그냥 commit --amend를 실행해주면 이전 commit massage에 대해 변경이 가능하다
revert
commit 삭제하기
rebase -i 나 reset을 이용해 삭제 할수 있지만 이미 공개된 경우에는 하기 힘들다
(안전하게 삭제하자)
따라서 해당 commit의 변경사항을 되돌리는 commit을 만들어서 해결한다
A -> B -> C -> B'
$ git revert HEAD HEAD는 지금 branch의 최신 commit을 가리키기 때문에 해당 commit을 지우는 commit을 생성한다⭐ 이때 HEAD~ 의 경우에는 ~ 1개당 1단계 전의 commit을 의미한다 즉 HEAD~~은 전전 commit을 의미한다
reset
필요없어진 commit 삭제
📋 reset의 종류( default는 mixed이다 )
HEAD의 위치 인덱스 작업트리 사용
soft 변경함 변경 안함 변경 안 함 커밋만 되돌릴때
mixed 변경함 변경함 변경 안 함 변경한 인덱스를 원래대로
hard 변경함 변경함 변경함 최근 커밋을 완전히 버리고 이전으로
$ git reset --hard HEAD~~ 전전의 commit 으로 완전히 돌아가라는 의미이므로 작업트리뿐만아니라 index도 다 변경되었다
$ git reset --hard ORIG_HEAD만약 실수로 reset을 하여 지워진 경우 reset 실행전의 상태로 돌아가게 하는 명령어ORIG_HEAD가 reset 전의 commit을 참조한다
cherry-pick
다른 브랜치의 특정 커밋을 복사해 현재 브랜치로 가져올 수 있다.
$ git cherry-pick <특정 commit 번호>지금 HEAD가 위치한 branch에 특정 commit이 추가된다. commit 번호는 git log로 확인할 수 있다
rebase -i
commit을 편집(수정, 삭제, 통합 )작업을 할 수 있다.
따라서 push전 commit내용을 정리할때나, 커밋에 누락된 파일을 추가할때 사용
$ git rebase -i HEAD~~HEAD에서 HEAD~ 까지 커밋이 표시상단의 pick을 squash로 바꾸면 해당 commit으로 통합된다그런데 이때 주의 해야할것이 최신의 commit으로 통합하는 것이고 squash를 적게 되면 그 이전의 commit이랑만 통합하므로여러개의 commit을 통합할시 여러개의 pick을 모두 여러개의 squash로 바꿔줘야 한다>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>edit을 입력해주면 해당 commit을 수정할 수 있다.-> 그럼 해당 commit을 수정해준 다음 add , git commit --amend를 해준다이 커밋 작업이 종료했다는것을 알리기 위해 git rebase --continue를 실행<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<만약 중간에 충돌이 발생하면 add , git rebase --continue를 바로 실행,중지하고 싶으면 git rebase --abort
$ git reset --hard ORIG_HEADreset 과 마찬가지로 rebase전의 commit상태로 돌아갈 수 있다.
2019년 6월 25일 화요일
#2 Git 분산버전관리시스템 - Basic - Branch
Branch
H
↗️ ↘️
A ➝ B ➝ C ➝ D
↘️ ↗️
X ➝ Y
동일한 소스코드로 협업을 할때 여러사람이 서로 다른 작업을 하게 되면
다른 버전의 code가 만들어지게 되는데 이런 작업을 손쉽게 돕는 기능이 Branch이다
말그대로 나뭇가지처럼 master branch에서 부터 뻗어 나와 우리가 사용하고 싶은
용도로 branch를 만들어 코드를 작성할 수있는 것이다.
(branch는 다른 branch의 영향을 받지 않는다)
이렇게 작업할경우 branch로 작업기록을 중간중간 남기게 되므로 문제가 발생했을 때
원인을 찾고 대책을 세우기 쉬워진다.
이렇게 branch를 나누어 작업을 한 이후에는 merge를 통해 branch를 모은다
참고할 만한 Branch 모델
협업하는 팀원들과 함께 branch의 작성규칙, 통합규칙을 정하는게 좋다
master branch 란?
repository를 처음 만들면 기본적으로 제공되는 branch로 새로운 branch를 만들어
checkout( 브랜치 이동 ) 을 하지 않는 이상 master에서 작업하게 됩니다.
- Main branch
✔ develop 브랜치는 통합 브랜치의 역할을 하며 이 브랜치를 기반으로 개발 진행, 안정적인 상태(app의 모든 기능 정상동작) 유지
- Feature branch or Topic branch
✔ 개발이 완료되면 develop branch로 병합
- Release branch
,
✔ branch 앞에 'release-'를 붙인다.
✔ 최종 버그 수정등의 개발을 수행
✔ 모든 준비가 끝나고 배포가능한 상태가 되면 master branch로 병합. commit에 tag번호
✔ release에서 발견한 버그사항은 develop branch에도 적용해야하므로 병합작업
- Hotfix branch
✔ branch 이름 앞에 'hotfix-'를 붙인다
✔ develop branch는 개발 진행중이기때문에 hotfix에 대처하기 힘드므로 master에서 분기해서 처리한다
✔ 처리 후에는 develop branch에도 병합해준다
1 . 브랜치 만들기
$ git branch < branch name > branch 를 만들어 주는 명령어
$ git branch branch 목록을 확인하는 명령어
2 . 브랜치 전환하기
$ git checkout <목표 branch> 현재 위치한 branch 에서 목표 branch로 이동< HEAD >가 변경된다.
$ git branch -b <목표 branch> 목표 branch를 생성함과 동시에 이동한다
브랜치를 checkout하면 해당 브랜치의 최신 commit사항이 작업트리에 반영된다
⇒ 즉 directory에 해당 branch에서 작업한 최신 commit이 반영된다
git log를 통해서 branch의 생성과 commit을 확인해 줄수 있다.
2 - 1 . Stash
branch의 변경사항에 대해 commit하지 않으면 checkout을 통해index와 작업 트리에 남아있는 내용들을 다른 브랜치에서 commit할 수도 있다.
그런데 이때 다른 branch에서 변경사항에 대해 충돌되는 부분이 이미 commit되어 있다면
commit을 하지 않았다 할지라도 checkout이 되지 않는다.
이럴때 사용할 수 있는것이 merge 혹은 stash이다
e.g)
A branch : 1.txt 생성 , 첫번째 줄에 111 입력
$ git branch B 를 통해 B branch 생성
A branch : 1.txt 의 첫번째 줄을 111222 로 수정 -- commit
$ git checkout B : 1.txt의 첫번째 줄은 111만 있음1.txt의 첫번째 줄을 111333으로 수정 --- commit X
$ git checkout A : Error 발생/ B branch에서 commit되지 않은 111333 부분이랑 A에서 commit된 111222가 서로 충돌을 일으킴
$ git stash위의 명령어를 통해 지금 위치한 branch의 1.txt 파일을 stash 한다stash란?merge는 아예 확정적으로 commit을 하는거라면 stash는 git내부의 가상의 어떠한 공간에 충돌이 일어나는 file을 넣음즉 임시 보관의 개념으로 사용할 수 있다.
$ git checkout A : 이제는 충돌하는 부분 없이 A로의 이동이 가능
$ git stash show stash 된 file들을 확인할 수 있다.
$ git stash pop stash 된 file을 다시 뽑아내어 git add , commit을 해줄수 있다.
이처럼 commit을 하지 않은 채 branch의 이동간에 conflict가 나는 경우
우리는 stash를 이용해서 해결할 수 있다.
3 . 브랜치 병합하기
$ git merge <commit 대상> 현재 사용중인 branch에 commit내용을 병합해준다.e.g 현재 (master) branch를 사용중이라고 하면git merge mybranch위의 명령어 실행시 mybranch의 변경사항을 master branch로 병합해준다.
3 - 1 . 브랜치의 충돌
A ➝ B ➝C ➝ D(master)[HEAD]
↘️
X ➝ Y(bugfix)
위의 D commit 과 Y commit 이 같은 내용을 서로 다르게 변경한 경우 conflict가 발생할 수 있는데
Git이 자동으로 충돌내용에 대해서 알려주기 때문에 직접 수정해서 다시 commit을 해줘야한다
A ➝ B ➝C ➝ D ➝ F(master)[HEAD]
↘️ ↗️
X ➝ Y (bugfix)
그럼 이렇게 F라는 merge commit이 새로 생성되게 된다
위와 같은 방법은 non fast-forward 병합이다.
3 - 2 . 브랜치 병합의 두 방법 ( merge & rebase )
rebase - 이력은 단순하지만 원래의 commit이 변경됨.
정확한 이력을 남겨야 할 필요가 있을때는 사용하면 안됨
fast- forward(빨리감기)
A ➝ B(master)[HEAD]
↘️
X ➝ Y ➝ Z(bugfix)
A ➝ B
↘️
X ➝ Y ➝ Z(master)(bugfix)[HEAD]
master branch가 변경된 이력이 없기 때문에
bugfix는 master branch의 이력을 모두 포함하고 있다
따라서 master브랜치가 빨리 감기된 모양을 가진다.
merge commit(병합 커밋)
A ➝ B ➝C ➝ D ➝ E(master)[HEAD]
↘️
X ➝ Y ➝ Z(bugfix)
A ➝ B ➝C ➝ D ➝ E ➝ F(master)[HEAD]
↘️ ↗️
X ➝ Y ➝ Z(bugfix)
bugfix가 분기한 이후 master의 변경사항이 있는 경우
양쪽의 변경을 모두 가져온 merge commit을 실행
፠ non fast-forward
fast forward를 할 수 있는 경우에도 master의 branch 확장을 통해non fast-forward 병합을 할수 있는데(그래서 F라는 commit 이 추가로 생성되었다)
A ➝ B➝➝➝➝➝➝➝➝ F(master)[HEAD]
↘️ ↗️
X ➝ Y ➝ Z(bugfix)
위와 같이 bugfix가 그대로 남기 때문에 브랜치 관리면에서 유용할 수 있다.
rebase(base를 변경한다)
$ git rebase <목표 branch> 지금 위치한(HEAD가 있는) 브랜치에 목표 branch의 변경사항을 update해준다만약 file간의 충돌이 발생한 경우에는 직접 수정해준 이후에 commit작업이 아닌git add <수정 file>git rebase --continue 명령어를 실행 시켜줘야한다 (rebase 취소는 git rebase --abort)
A ➝ B ➝C ➝ D(master)
↘️
X ➝ Y(bugfix)[HEAD]
A ➝ B ➝C ➝ D(master) ➝ X' ➝ Y'(bugfix)[HEAD]
bugfix branch를 master 브랜치에 rebase 하면
bugfix branch의 이력이 master branch 뒤로 이동한다
( 즉 bugfix branch의 base를 B에서 D로 바꾸어 변경사항도 적용해주는 것이다)
따라서 master branch의 이력를 변경하기 위해 이제는 fast-forward 를 통해 병합해주자
4 . 브랜치 삭제
$ git branch -d <branch name> branch를 삭제하는 명령어
가장 많이 본 글
-
🔌 Network - HTTP 개요 브라우저에 URL 을 입력하면 브라우저 는 URL의 의미에 따라 request massage 를 만든다 그리고 이 massage를 web server 에 보내주게 되는데 메세지를 보내는것은 디...