Git/ 자바스크립트

우혁·2024년 1월 9일
7

코드잇 스프린트

목록 보기
3/22

🐱 GitHub

- 팀을 만들기 위한 기능: Organization

GitHub의 Organization은 팀원들을 한 곳에 모아 프로젝트와 저장소를 효율적으로 관리하는 팀 협업 도구이다.

이 기능은 주로 회사나 대규모 조직에서 권한 관리와 보안을 향상시키기 위해 사용된다.
Organization 기능을 활용하면 다양한 영역으로 나눠진 저장소를 한데 모아, 프로젝트 관리를 간소화할 수 있다.

- Project

Project는 할 일 목록 등을 관리하는 도구로 프로젝트의 진행 상황을 시각화하고 작업의 우선순위를 정할 수 있다.

- Teams

Teams 기능을 통해 소속된 collaborator를 목적에 따라 그룹화할 수 있다.

- Issues

Issues는 버그 추적과 프로젝트 관련 토론을 위한 중요한 기능이다.

- Pull Requests(PR)

다른 사용자들에게 자신이 작업한 코드 변경 사항을 검토하고 병합해달라고 요청하는 기능이다.
다른 사용자들은 PR을 검토하고 의견을 주고 받을 수 있으며, 코드 변경의 품질을 개선하고 버그를 예방하는 데에 중요한 역할을 한다.

- Code Reviews

GitHub에서 코드 리뷰를 위한 기능을 제공한다.


- Pull Request(PR)란?

자신의 작업한 내용을 검토하고 머지해 달라고 요청하는 GitHub의 기능이다.

개인 프로젝트에서의 PR 사용법

PR을 통해 코드의 변경 사항을 재검토하면서 오류를 발견하고, 문서로 코드를 설명하지 않더라도 PR 자체가 의미를 가지는 코드의 단위이다. 즉 변경 점의 최소 단위인 commit 단위의 기록이, feature 단위의 기록이 PR로 남기 때문에 일종의 기록, 자동화된 documentation의 기능을 수행하는 것입니다.

팀 프로젝트에서의 PR 사용법

모든 팀원이 코드 리뷰를 통해 다른 사람이 작성한 코드를 확인하면서 지식을 공유하고 코드의 품질을 개선할 수 있습니다.

- Pull Request의 상태

- Open

Open상태는 PR은 아직 검토가 완료되지 않았거나, 추가적인 작업이 필요한 상태를 말한다.
이 상태에서는 더 많은 커밋을 추가하거나, 토론을 진행하며 수정을 요청할 수 있다.

- Merged

Merged 상태는 PR은 소스 코드의 기본 브랜치로 병합된 상태를 말한다.
PR 화면에서 Merge 버튼을 누르게 되면 해당 상태로 변경하게 된다.

- Closed

Closed 상태의 PR은 거부되었거나, 더 이상 유효하지 않은 PR을 말한다.
이 PR은 병합되지 않았지만 더 이상 필요하지 않거나 다른 이유로 인해 종료된 상태입니다.

💡 Closed와 Merged는 결국 Closed 상태이기 때문에 Closed에서 모두 확인이 가능하다!

📝 정리하기

git pull -> git checkout -b [브랜치 명] -> git add & git commit -> git push -> PR 생성


- 두 개의 브랜치를 머지하는 방법

1. merge commit을 만들며 합치기

  • 두 브랜치의 변경 사항을 모두 유지하며 병합한다.
  • 각 브랜치의 변경 사항이 과거의 커밋으로 보존되고, 새로운 커밋이 추가되어 병합이 완료된다.
    장점: 브랜치의 히스토리를 모두 유지하면서 변경 사항을 병할할 수 있다는 장점이 있다.
    단점: 커밋 히스토리가 복잡해질 수 있다.

2. squash and merge 하기

  • 브랜치에서의 모든 변경 사항을 하나의 커밋으로 압축하여 병합하는 방식
  • 이 방식은 각각의 커밋에서 발생한 모든 변경 사항을 병합 후에 하나의 새로운 커밋을 생성한다.
    장점: 커밋 히스토리를 간단하게 유지할 수 있는 장점이 있다.
    단점: 작업의 상세한 이력을 잃게 된다.

squash merge

3. rebase and merge 하기

  • 현재 브랜치를 target 브랜치에 재위치 시킨 후에 병합하는 방식
  • 커밋 히스토리가 선형으로 유지된다.
    장점: 깨끗하고 선형적인 커밋 히스토리를 만들어 준다는 장점이 있다.
    단점: 관련된 커밋의 ID들이 모두 바뀌게 되어 혼란을 초래할 수 있다.

rebase merge

📝 정리하기

merge commit: 머지 커밋을 만든다.
squash and merge: 브랜치에서의 모든 변경 사항을 하나의 커밋으로 합축하여 머지하는 방식
rebase and merge: target브랜치의 HEAD(최신 커밋)로 옮긴다.


- Fork해서 PR 만들기

Fork의 개념

기존 레포지토리에서의 모든 변경 사항을 담고 있는, 내가 소유한 새로운 레포지토리를 만들어주는 기능과
이미 존재하는 원격 레포지토리를 사용자의 계정으로 복사를 하는 기능이다.
Fork된 레포지토리는 기존 레포지토리와 완전히 분리되어 있으므로 사용자는 자신의 레포지토리에서 자유롭게 변경 사항을 반영할 수 있다.

Fork로 PR을 만드는 이유

- 브랜치를 사용하는 방식

브랜치를 사용한 방식은 원본 저장소에 직접 접근하여 작업하고, 변경 사항을 PR로 제안하는 방식이다.
이 방식은 작업의 효울성이 좋고 원본 저장소에서 직접 협업할 수 있다는 장점이 있어 일반적인 규모의 팀이나 팀원들은 이 방식으로 협업하는 것이 일반적이다

- Fork를 사용하는 방식

Fork 된 저장소에서 작업을 진행하며, 원본 저장소의 소유자에게 PR을 제안하는 방식이다.
오픈소스 프로젝트(다양한 규모의 팀, 매우 큰 규모의 프로젝트)는 Fork를 사용해 PR을 생성하는 대표적인 예시이다.

Fork로 PR 생성하는 방법

1. GitHub에서 원하는 프로젝트의 페이지로 이동한다.
2. 우측 상단에 있는 Fork 버튼을 클릭하여 해당 프로젝트를 자신의 계정으로 Fork 한다.
3. Fork 된 저장소로 이동하고, 변경 사항을 반영할 브랜치를 생성한다.
4. 변경 사항을 커밋하고 푸쉬한다.
5. GitHub 사이트에서 Fork 된 저장소로 이동한 후, New pull request 버튼을 클릭한다.
6. 변경 사항을 반영할 원본 저장소와 브랜치를 선택한다.
7. Pull Request를 작성하고 제출한다.


- PR 충돌 해결 방법

두 브랜치를 머지하려고 할 때 Git은 자동으로 병합을 시도하는데, 이 과정에서 두 브랜치가 동일한 파일 또는 동일한 부분을 수정한 경우에 Git은 충돌이 발생했다고 판단합니다.

Git은 충돌이 발생한 파일을 특수한 형식으로 표시하여 사용자가 해결할 수 있도록 도와준다.
충돌 부분은 <<<<<<, =======, >>>>>>과 같은 마커로 표시하고 이 마커 사이에는 충돌을 발생시킨 변경 사항이 포함되어 있습니다.

1. Resolve conflicts 버튼을 눌러 해결하기, 버튼을 누르게 되면 GitHub에서 main을 사용자 브랜치로 병합하게 된다.

  • Accept Current: 현재 브랜치의 내용을 선택
  • Accept Incomming: 가져오는 브랜치의 내용을 선택하는 것
  • Accept Both: 두 가지 모두를 선택하는 것
  • <<<===>>> : 두 코드를 보고 직접 수정하는 것

2. 로컬에서 충돌 해결 하기

2-1. 텍스트 편집기로 해당 파일을 열어서<<<===>>> 로 표시 돼 있는 부분을 직접 수정
2-2. 수정된 파일을 저장 한 후, git add & git commit을 사용하여 해당 파일의 병합이 완료되었음을 Git에 알리기
2-3. git push를 수행하면 성공적으로 충동을 해결할 수 있다.


- PR 충돌을 최소화하는 방법

1. 최신 코드 유지

프로젝트를 진행할 때, 보통 하나의 메인 브랜치를 기반으로 새로운 기능을 개발하기 위한 브랜치를 생성하는데,
개발 기간이 길어질수록 메인 브랜치와 개발 중인 브랜치의 간의 차이가 커지면 충돌 가능성도 증가한다.

이 문제를 해결하기 위한 간단한 방법은 주기적으로 원본 브랜치의 최신 변경 이력을 메인 브랜치로 가져오는 것이다.

2. 작은 PR 만들기

PR의 규모가 작아지면 변화하는 코드의 양도 적어지고, 그 코드를 작성하는데 들어가는 시간도 줄어들기 때문에
메인 브랜치와의 차이가 적다는 것을 의미하고 충돌이 발생하더라도 코드의 일부만 문제가 발생했을 가능성이 높다.

3. 파일을 작게 만들기

코드의 충돌은 대체로 파일 단위로 발생한다. 큰 파일은 그만큼 충돌이 발생할 가능성이 높으면 작은 파일에서 발생한 충돌을 해결하는 것이 큰 파일의 충돌을 해결하는 것보다 상대적으로 간단한 가능성이 높다.

4. 동료들과 많은 커뮤니케이션 수행

커뮤니케이션을 통해 인력과 기능을 적절하게 분배하고, 우선순위에 따라 서로 밀접하지 않은 기능을 먼저 개발하게 된다면 충돌은 자연스럽게 줄어들 수 있다.


- Git Flow 브랜치 전략

브랜치 관리에 명확한 기준이 없다면 아래와 같은 수 많은 의문점이 생기고 프로젝트는 엉망이 될 것 이다.

  • 이 브랜치는 어떤 목적으로 생성된 것 인지?
  • 이 브랜치는 어떤 커밋에서 분기된 것 인지?
  • 어떤 브랜치에서 내 브랜치를 생성해야 하는지?
  • 내 브랜치는 어디에 병합해야 하는지?
  • 어떤 브랜치가 최신인지?

- Git Flow 구조

Git Flow는 크게 Main, Develop, Supporting 브랜치로 구분하여 관리한다.
이 때 Supporting 브랜치는 다시 Feature, Release, Hotfix 브랜치로 나뉜다.

Main 브랜치

출시 가능한 프로덕션 코드를 모아두는 브랜치이다. 프로젝트 시작 시 생성되며, 프로세스 전반에 걸쳐 유지된다. 배포된 각 버전을 Tag를 이용해 표시해둔다.

Develop 브랜치

다음 버전 개발을 위한 코드를 모아두는 브랜치이다. 개발이 완료되면 Main 브랜치로 머지된다.

Feature 브랜치

하나의 기능을 개발하기 위한 브랜치이다. Develop 브랜치에서 생성하며, 기능이 개발 완료되면 다시 Develop 브랜치로 머지된다. 이 때 주의점은 Fast-Forward로 머지하지 않고, merge commit을 생성하며 머지를 해주어야 한다. 그 이유는 히스토리가 특정 기능 단위로 묶이게 하기 위해서이다.
네이밍은 feature/branch-name과 같은 형태로 생성한다.

Release 브랜치

소프트웨어 배포를 준비하기 위한 브랜치이다. Develop 브랜치에서 생성하며, 버전 이름 등의 작은 데이터를 수정하거나 배포 전 사소한 버그를 수정하기 위해 사용된다. 배포 준비가 되면 Main과 Develop 브랜치에 둘다 머지한다. 이 때 Main 브랜치에는 Tag를 이용하여 버전을 표시한다.
네이밍은 release/v1.1과 같은 형태로 생성한다.

Hotfix 브랜치

이미 배포된 버전에 문제가 발생했다면, Hotfix 브랜치를 사용하여 문제를 해결한다. Main 브랜치에서 생성하며, 문제 해결이 완료되면 Main과 Develop 브랜치에 둘다 머지한다.
네이밍은 hotfix/v1.0.1과 같은 형태로 생성한다.


Git Flow의 한계

Git Flow는 명시적으로 버전관리가 필요한 스마트폰 어플리케이션, 오픈 소스 라이브러리/ 프레임워크 등의 프로젝트에 적합한다. 웹 어플리케이션 특성상 사용자는 항상 최신의 단일 버전만을 사용하게 된다. 또한 웹 어플리케이션은 하루에 여러번 릴리즈될 수 있기 때문에 Git Flow는 적합하지 않다.


💻 자바스크립트(JavaScript)

- 객체 for .. in문

객체의 프로퍼티 네임(key)으로 숫자형을 사용할 수 있지만 실제로 사용될 때는 문자로 형 변환이 되어 사용되고, 접근할 때도 대괄호표기법([], 브라켓)으로만 접근이 가능하다.

정수형 프로퍼티 네임에 for..in문을 사용하면 정수형 프로퍼티 네임을 오름차순으로 정렬하고, 나머지 프로퍼티들은 추가한 순서대로 정렬하는 특징있다.

let obj = {
  3: '정수3',
  name: 'codeit',
  1: '정수1',
  birthDay: '2001.2.09',
  2: '정수2',
};

for (let key in obj) {
  console.log(key);
}

// 결과, 객체에 정수 순서는 3, 1, 2로 되어있지만 출력은 오름차순으로 정렬되었다.
// 만약 정수형 프로퍼티에 따옴표를 붙여 문자열처럼 만들더라도('3','1','2') 결과는 똑같다
1
2
3
name
birthDay

이걸 배우고 바로 생각이 들었던게 코딩테스트 문제 풀때 유용하게 사용할 수 있을 것 같다는 생각이 들어서 정리하게 되었다.


- Date 객체

간단하게 시간 정보 알아내기

let myDate = new Date(); //Fri Dec 29 2023 13:21:06 GMT+0900 (한국 표준시)

console.log(myDate.toLocaleDateString()); // 2023. 12. 29. (년.월.일)
console.log(myDate.toLocaleTimeString()); // 오후 1:21:06 (시:분:초)
console.log(myDate.toLocaleString()); // 2023. 12. 29. 오후 1:21:06 (년.월.일 시:분:초)

범위를 벗어나는 값을 설정한다면?

Date 객체에서 범위를 벗어나는 값을 설정하려고 하면 자동으로 날짜를 수정해준다.

let myDate = new Date(2001, 0, 32); // 2001년 1월 32일은 없는 날짜이다.

// 자동으로 2월 1일로 수정되어 출력된다!
console.log(myDate) // Mon Feb 01 2001 00:00:00

⭐️ 날짜간의 차이 구하기! ⭐️

let myDate1 = new Date(2001, 2, 9);
let myDate2 = new Date(2001, 2, 10);

let timeDiff = myDate2 - myDate1;
console.log(timeDiff); // 86400000 (ms단위로 계산된다.)
console.log(timeDiff / 1000); // 86400 (ms -> s 계산)
console.log(timeDiff / 1000 / 60) // 1440 (ms -> s -> m 계산)
console.log(timeDiff / 1000 / 60 / 60) // 24 (ms -> s -> m -> h 계산)
console.log(timeDiff / 1000 / 60 / 60 / 24) // 1 (ms -> s -> m -> h -> d 계산)

- ⭐️ Math 객체 ⭐️

거듭제곱(Exponentiation)

제곱의 개념 '2의 3승'(혹은 '2의 세제곱')을 하면 2를 세 번 곱한다는 뜻이다.
자바스크립트에서 Math.pow(x, y)를 하면 xy승의 결괏값이 리턴된다.

console.log(Math.pow(3, 4)); // 81
console.log(3 ** 4) // 81, **을 사용하면 거듭제곱과 같은 기능을 할 수 있다. 

제곱근(Square Root)

제곱근의 개념은 제곱은 반대라고 생각할 수 있다. Math.sqrt(x)를 하면 x의 제곱근이 리턴된다.

console.log(Math.sqrt(25)); // 5
console.log(Math.sqrt(49)); // 7

반올림(Round)

Math.round(x)를 하면 x의 반올림된 값이 리턴된다. 소수점 부분이 0.5이상이면 가장 가까운 정숫값으로 올라가고 0.5미만이면 가장 가까운 정숫값으로 내려간다.

console.log(Math.round(2.3)); // 2, 0.5미만
console.log(Math.round(2.49)); // 2, 0.5미만
console.log(Math.round(2.5)); // 3, 0.5이상
console.log(Math.round(2.6)); // 3, 0.5이상

버림과 올림(Floor and Ceil)

Math.floor(x)를 하면 x의 버림 값이, Math.ceil(x)를 하면 x의 올림 값이 리턴된다. 이 경우에는 소수 부분이 얼마인지는 상관이 없다.

// floor
console.log(Math.floor(2.4)); // 2
console.log(Math.floor(2.49)); // 2
console.log(Math.floor(2.8)); // 2
// ceil
console.log(Math.ceil(2.4)); // 3
console.log(Math.ceil(2.49)); // 3
console.log(Math.ceil(2.8)); // 3

반올림, 반내림을 하려면 Math.round / 무조건 올림, 내림을 하려면 Math.floor(), Math.ceil()을 사용해야겠다!!

난수(Random)

Math.random을 하면 0 이상 1 미만의 값이 랜덤으로 리턴된다.

console.log(Math.random()); // 0.3608... 0 ~ 1미만의 값 
console.log(Math.random() * 10); //1.4555... 0 ~ 10미만의 값
console.log(Math.random() * 100); // 72.2550... 0 ~ 100미만의 값
console.log(Math.random() * 1000); // 794.7040... 0 ~ 1000미만의 값

0~100까지의 랜덤 정수를 만들고 싶다면 이렇게 하면 될 것 같다!

console.log(Math.floor(Math.random() * 100)); // 0 ~ 99이하의 숫자, 100은 나오지 않는다. 
console.log(Math.floor(Math.random() * 101)); // 0 ~ 100이하의 숫자, 100도 포함된다. 

- ⭐️ mutable vs immutable ⭐️

가장 중요한 차이는 배열은 mutable(바뀔 수 있는) 자료형 이지만 문자열은 immutable(바뀔 수 없는)자료형이라는 것이다.

배열은 인덱스로 접근해서 할당 연산자를 통해 요소를 수정할 수 있지만 문자열은 변수에 할당된 문자열을 바꾸고싶다면 새로운 문자열을 지정해줘야 한다.

// 배열은 mutable(바뀔 수 있다!)
let myArray = ['C', 'o', 'd', 'e', 'i', 't'];
myArray[0] = 'B';
console.log(myArray); // ['B', 'o', 'd', 'e', 'i', 't']

// 문자열은 immutable(바뀔 수 없다!)
let myString = 'Codeit';
myString[0] = 'B';
console.log(myString); // 'Codeit'

- ⭐️ 기본형과 참조형 ⭐️

기본형: Number, String, Boolean, null, undefined
참조형: Object, Array, function, RegExp

// 기본형 예제
let x = 3;
let y = x;
console.log(x); // 3
console.log(y); // 3
y = 5;
console.log(x); // 3
console.log(y); // 5, y에 5를 재할당해서 5로 바뀌었다.
// 참조형 예제
let obj = {name: '우혁'};
let obj1 = obj;
console.log(obj); // {name: '우혁'}
console.log(obj); // {name: '우혁'}
obj1.age = 22;

// 분명 obj1에만 age 프로퍼티를 추가했는데 obj에도 추가가 되었다.
console.log(obj); // {name: '우혁', age: 22}
console.log(obj); // {name: '우혁', age: 22}

변수에 참조형 값을 할당한 경우에는 객체 값의 메모리 주소가 생성되고, 다른 변수에 값을 할당하면 메모리 주소가 공유가 된다.


- ⭐️ const는 변수? 상수? ⭐️

실제로 const의 역할은 값이 변하지 않는 상수는 맞지만, 값을 재할당하면 안되는 경우에는 const로 변수를 생성하는 것이 안전하다

네이밍 방법

const 변수(Variable): 변수와 같이 camelCase형식으로 짓는다. ex) userName
const 상수(constant): 모두 대문자, 띄어쓰기와 같은 요소는 언더바(_)를 사용한다. ex) USER_NAME


- ⭐️ 옵셔널 파라미터(Optional Parameter) ⭐️

파라미터(parameter)에 기본 값(defualt value)을 설정하여 함수를 호출할 때 꼭 파라미터에 값을 주지않아도 기본 값이 출력된다.

옵셔널 파라미터 예제

문제1.

function userInfo(name, age, mbti ="ENTP"){
  console.log(`이름: ${name}, 나이: ${age}, MBTI: ${mbti}`);
}
userInfo("맹구", 5, "INFP") // 이름: 맹구, 나이: 5, MBTI: INFP

// 파라미터 mbti에 값을 주지 않아서 기본 값이 ENTP가 출력되었다.
userInfo("짱구", 5); // 이름: 짱구, 나이: 5, MBTI: ENTP

문제2.

function userInfo(name, age = 5, mbti){
  console.log(`이름: ${name}, 나이: ${age}, MBTI: ${mbti}`);
}

// 옵셔널 파라미터는 파라미터의 제일 마지막에 설정해야 한다!
userInfo("짱구", "ENTP"); // 이름: 짱구, 나이: "ENTP", MBTI: undefined

- ⭐️ 변수의 스코프 ⭐️

전역 스코프: 어디에서든 참조가 가능하다.
↪ 전역 변수: 전역 스코프에서 선언된 변수, 어디서든 참조가 가능하다.
지역 스코프: 블록 안, 함수 내에서만 참조가 가능하다.
↪ 지역 변수: 지역 스코프에서 선언된 변수, 지역 스코프 안에서만 참조가 가능하다.

var vs let vs const 키워드 자세히 알기

const 키워드

  • 스코프: 블록
  • 재할당: X
  • 재선언: X

let 키워드

  • 스코프: 블록
  • 재할당: O
  • 재선언: X

var 키워드

  • 스코프: 함수
  • 재할당: O
  • 재선언: O
for(let i = 0; i<3; i++){
  console.log(i); // 0, 1, 2
} 
console.log(i); // Error, 지역 변수는 지역 스코프 밖에서 사용할 수 없다.
// 하지만 var로 i를 선언하면 전역 변수처럼 모든 스코프에서 접근이 가능하다.

주의사항🔥

1. 선언 없이 변수를 할당하면 해당 변수는 var로 선언한 변수처럼 취급된다.
2. 코드를 짤 때 전역 변수를 최소화하자! -> 의도하지 않은 로직에 의한 문제 발생을 줄일 수 있다.
↪ let 선언자를 사용하여 변수 선언, var 선언자 사용 금지

profile
🏁

0개의 댓글

관련 채용 정보